Automated Repository Manager
& Deployment Daemon

Gadirpull is a production-grade, versatile file synchronization and continuous deployment daemon for Linux systems. It monitors, syncs, and deploys content from multiple sources, including Git repositories, local directories, and network shares. The daemon continuously manages multiple repositories simultaneously and provides a real-time web dashboard and gadirpull cli for control. Gadirpull handles auto-deployment, keeps development environments in sync, and manages microservices across distributed infrastructure.

Get Started Explore Features

Gadirpull_linux_amd64
curl -LO https://github.com/amainyebriggs/gadirpull/releases/download/v1.2/gadirpull_linux_amd64 && sudo chmod +x gadirpull_linux_amd64 && sudo mv gadirpull_linux_amd64 gadirpull
Gadirpull_linux_arm32
curl -LO https://github.com/amainyebriggs/gadirpull/releases/download/v1.2/gadirpull_linux_arm32 && sudo chmod +x gadirpull_linux_arm32 && sudo mv gadirpull_linux_arm32 gadirpull
Gadirpull_linux_arm64
curl -LO https://github.com/amainyebriggs/gadirpull/releases/download/v1.2/gadirpull_linux_arm64 && sudo chmod +x gadirpull_linux_arm64 && sudo mv gadirpull_linux_arm64 gadirpull
Gadirpull_linux_X86
curl -LO https://github.com/amainyebriggs/gadirpull/releases/download/v1.2/gadirpull_linux_X86 && sudo chmod +x gadirpull_linux_X86 && sudo mv gadirpull_linux_X86 gadirpull
Git / SSHNFS / SMBSSHFS / FTPSystemdWeb DashboardPAM AuthMulti‑User

Core Capabilities

Everything you need for continuous delivery

Full lifecycle management — synchronization, builds, service control, backups, conflict resolution, and hardened security.

Multi-Source Sync

Git (HTTP/SSH), local directories (file://), NFS, SMB/CIFS, SSHFS, FTP/FTPS. SHA256 hashing + bidirectional conflict detection.

Real-Time Dashboard

Live CPU, memory, disk I/O, network with Chart.js graphs. Repository controls, backup browser, diff viewer, and SSE updates.

Security Hardened

PAM auth, rate limiting, command whitelist/blacklist, systemd-run isolation, systemd-creds encryption, and ProtectSystem=strict.

Backup & Restore

Automatic ZIP backups before each sync (up to 10 per repo). One-click restore via dashboard or CLI with metadata tracking.

Build & Deploy

Post-sync build commands (npm, make, composer). Systemd service creation with start/stop/restart, resource limits (mem/cpu).

Conflict Resolution

Detects modified_both, deleted_local, added_both. Interactive resolver with side-by-side diff viewer, merge markers.

Email Alerts

SMTP with TLS. Filter events: pull, clone, buildcmd, delete, restore — success, failure, or both. Test verification.

Multi-User Isolation

Per-repo ownership (AddedBy). Only owner or root can view, modify, or delete repos in shared environments.

Reverse Proxy

One‑command nginx/apache/traefik/haproxy setup with Certbot SSL, static file serving, and 30‑day asset caching.

gadirpull-tester

Auto‑detects test/build commands for Node, Python, Go, Rust, Java, PHP, Ruby, .NET, Flutter, C/C++ and more.

Network Shares

Temporary or persistent mounts (systemd/fstab). Credentials stored with 0600 perms. FTP fallback to local copy.

Metrics & Logging

Pull statistics, recent pulls history (last 100), per-repo action logs with command output, uptime, goroutines.

Gadirpull Web Dashboard
Web dashboard — CPU/memory graphs, repository controls, service status, and conflict resolution UI.

Get up and running in minutes

Download the binary, install globally, and start as a daemon.

# Download latest release
curl -LO https://github.com/amainyebriggs/gadirpull/releases/download/v1.2/gadirpull_linux_amd64
sudo chmod +x gadirpull_linux_amd64

# Install globally
sudo mv gadirpull_linux_amd64 /usr/local/bin/gadirpull
hash -r

# Or run without global install
sudo ./gadirpull_linux_amd64 -d
# Download with wget
wget -O gadirpull https://github.com/amainyebriggs/gadirpull/releases/download/v1.2/gadirpull_linux_amd64
sudo chmod +x gadirpull

# System-wide install
sudo cp gadirpull /usr/local/bin/
hash -r

# Run locally
sudo ./gadirpull -d
# Create and start systemd daemon (port :8445 by default)
sudo gadirpull --service

# After service is created
sudo systemctl status gadirpull-daemon
sudo systemctl restart gadirpull-daemon

# View live logs
sudo journalctl -u gadirpull-daemon -f

# Stop daemon service
sudo systemctl stop gadirpull-daemon
# Initialize service and web dashboard
gadirpull --service

# Add your first repository
gadirpull -r https://github.com/user/awesome-project.git

# Or add with build + systemd service
gadirpull -r https://github.com/user/node-app.git -s -buildcmd "npm install" -startcmd "node server.js"

# Open dashboard
 Visit http://localhost:8445 (or your server IP)
CLI Reference

All command-line flags

Full control over repositories, authentication, services, security policies, and proxy configuration.

Repository & Auth

-r repo Add or target repository
-delete -r repo Delete repository
-list List all tracked repositories
-find repo Find repository location
-auth <type> none / token / password / ssh
-token <value> Token or password
-user <username> Username for HTTPS auth
-sshkey <path> SSH private key path
-b <branches> Comma-separated branches
-c <seconds> Poll interval (default 60) or "webhook"

Proxy & Files

-proxy <type> nginx / apache / traefik / haproxy
-proxydomain <domain> example.com or "#" catch-all mode
-proxystaticpath <path> Serve static files, e.g., "index.html"
-proxyssl <mode> false / true / certbot
-proxycache 30-day static asset caching
-manageProxy Interactive wizard for proxy config
-createfile text|file Create file in repository
-filename <name> Destination filename
-text "<content>" Inline text content

Service & Deployment

-d Start daemon with dashboard
-service Create/remove systemd daemon service
-s Create systemd service for repository
-authsetup Interactive user login mode management (add/update/delete users with PAM or password base auth)
-buildcmd <cmd> Build command after clone/update
-startcmd <cmd> Service start command
-allowedcmd <cmds> Command whitelist (comma-separated)
-disallowedcmd <cmds> Command blacklist
-noexecpath <dirs> Block execution in directories
-memlimit <limit> Memory limit (512M, 1G, 2G)
-cpulimit <n> CPU quota (e.g., 1, 1.5)

Security & Daemon

-envencrypt <files> Encrypt files with systemd-creds
-envunencrypt Remove encrypted credentials
-host <addr> Daemon listen address
-port <port> Daemon listen port (default 8445)
-webhook Enable webhook API endpoint
-f <path> Custom folders config path

No external database — JSON configuration in /etc/gadirpull/repos.json  |  Credentials: /etc/gadirpull/credentials/  |  Backups: /etc/gadirpull/backups/

Common usage patterns

From basic repo tracking to full CI/CD pipelines with microservices, network shares, daemon control, and security hardening.

# Add a repository — main branch, 60s poll interval by default
gadirpull -r https://github.com/user/repo.git

# Track a specific branch
gadirpull -r https://github.com/user/repo.git -b develop

# Track multiple branches simultaneously (comma-separated)
gadirpull -r https://github.com/user/repo.git -b main,develop,staging,feature-x

# Custom poll interval — check every 120 seconds
gadirpull -r https://github.com/user/repo.git -c 120

# Add a repo into a specific directory (run from that dir)
cd /var/www/ && gadirpull -r https://github.com/user/webapp.git

# Add multiple repos in different folders
cd /home/user/projects && gadirpull -r https://github.com/user/backend.git
cd /var/services   && gadirpull -r https://github.com/user/api-gateway.git

# Webhook mode — sync triggered by push event instead of polling
gadirpull -r https://github.com/user/repo.git -c webhook

# List all tracked repositories
gadirpull -list

# Find where a specific repo is cloned
gadirpull -find https://github.com/user/repo.git

# Delete a repository (removes files and its systemd service)
gadirpull -r https://github.com/user/repo.git -delete
# HTTPS — GitHub Personal Access Token (ghp_...)
gadirpull -r https://github.com/user/private-repo.git -auth token -token ghp_xxxxxxxxxxxx

# HTTPS — username + password (GitLab, Gitea, Bitbucket, etc.)
gadirpull -r https://gitlab.com/user/repo.git -auth password -user myusername -token mypassword

# SSH — uses default key at ~/.ssh/id_rsa automatically
gadirpull -r git@github.com:user/repo.git

# SSH — specify a custom deploy key
gadirpull -r git@github.com:user/repo.git -auth ssh -sshkey /home/user/.ssh/deploy-key

# SSH — custom key, production branch, 30s interval
gadirpull -r git@github.com:user/repo.git -auth ssh -sshkey /etc/ssh/repo-key -b production -c 30

# SSH — key stored in /root for a system-level deploy
gadirpull -r git@github.com:company/infra.git -auth ssh -sshkey /root/.ssh/infra_key -b main

# Private GitLab with token + webhook trigger + service
gadirpull -r https://gitlab.internal.com/team/api.git \
  -auth token -token glpat-xxxxxxxxxxxx \
  -b main -c webhook -s -startcmd "node server.js"
# Node.js — systemd service auto-start on boot, auto-restart on crash
gadirpull -r https://github.com/user/node-app.git -s -startcmd "node server.js"

# Python — install deps then start gunicorn
gadirpull -r https://github.com/user/python-app.git -s \
  -buildcmd "pip install -r requirements.txt" \
  -startcmd "gunicorn app:app"

# Python — run Django migrations + collectstatic then serve
gadirpull -r https://github.com/user/django-site.git -s \
  -buildcmd "pip install -r requirements.txt && python manage.py migrate && python manage.py collectstatic --noinput" \
  -startcmd "gunicorn mysite.wsgi:application --bind 0.0.0.0:8000"

# Go — compile binary then run it
gadirpull -r https://github.com/user/golang-api.git -s \
  -buildcmd "go build -o api-server" \
  -startcmd "./api-server"

# Rust — cargo build release then run
gadirpull -r https://github.com/user/rust-api.git -s \
  -buildcmd "cargo build --release" \
  -startcmd "./target/release/api"

# PHP Laravel — composer deps + artisan serve
gadirpull -r https://github.com/user/laravel-app.git -s \
  -buildcmd "composer install --no-dev && php artisan config:cache" \
  -startcmd "php artisan serve --host=0.0.0.0 --port=8080"

# Docker Compose service
gadirpull -r https://github.com/user/docker-app.git -s \
  -startcmd "docker-compose up -d"

# Service with memory and CPU resource limits
gadirpull -r https://github.com/user/app.git -s \
  -startcmd "node server.js" \
  -memlimit 512M -cpulimit 1.5

# Service with webhook trigger — deploy instantly on git push
gadirpull -r https://github.com/user/node-app.git \
  -c webhook -s -startcmd "npm start"

# Update existing repo to add a service retroactively
gadirpull -r https://github.com/user/app.git -s -startcmd "node server.js"
# Simple make build
gadirpull -r https://github.com/user/app.git -buildcmd "make build"

# Chain multiple commands with &&
gadirpull -r https://github.com/user/app.git \
  -buildcmd "npm install && npm run build"

# Run DB migrations after every pull
gadirpull -r https://github.com/user/app.git \
  -buildcmd "python manage.py migrate"

# Test suite — continue even if tests fail (|| true)
gadirpull -r https://github.com/user/app.git \
  -buildcmd "go test ./... || true"

# Restart a separate system service after every sync
gadirpull -r https://github.com/user/app.git \
  -buildcmd "systemctl restart myapp"

# Combine build + service restart in one command
gadirpull -r https://github.com/company/app.git \
  -buildcmd "make test && make build && systemctl restart app"

# Create an .env file on first clone (createfile)
cd /var/www && gadirpull -r https://github.com/company/webapp.git \
  -b production -s -startcmd "node server.js" \
  -buildcmd "npm install && npm run build" \
  -createfile text -filename .env -text "NODE_ENV=production\nPORT=4000"

# Write a .version file on deploy
gadirpull -r https://github.com/company/app.git \
  -buildcmd "make build" \
  -createfile text -filename .version -text "v1.0.0"

# Encrypt sensitive files with systemd-creds after build
gadirpull -r https://github.com/company/auth.git -s -startcmd "node server" \
  -buildcmd "npm install" \
  -envencrypt ".env,secrets.json,db-cert.crt"
── NFS ───────────────────────────────────────────────────────────
# Basic NFS mount and sync
gadirpull -r nfs://192.168.1.100/exported/path

# NFS with specific export path
gadirpull -r nfs://server.example.com/srv/nfs/share

# NFS with auth credentials (if required by the export)
gadirpull -r nfs://server/share -user username -token password

# NFS — persistent mount via systemd unit (select option 2 when prompted)
gadirpull -r nfs://192.168.1.100/exports/data
# → Will prompt: Choose [1/2/3] — select 2 for systemd persistent

# NFS with validate script run on every sync
gadirpull -r nfs://storage.local/database -c 10 -b dev -buildcmd "./validate.sh"

── SMB / CIFS ────────────────────────────────────────────────────
# Basic SMB (guest access)
gadirpull -r smb://server/sharename

# SMB with username + password
gadirpull -r smb://192.168.1.50/shared -user myuser -token mypassword

# CIFS (alias for SMB) — domain user
gadirpull -r cifs://server/documents -user domain\\user -token pass123

# SMB — persistent mount via /etc/fstab (select option 3 when prompted)
gadirpull -r smb://storage.local/files -user smbuser -token secret
# → Will prompt: Choose [1/2/3] — select 3 for fstab persistent

# Full SMB deployment pipeline — fetch releases, build, serve
gadirpull -r smb://buildserver/releases -b main \
  -buildcmd "npm ci && npm run build" \
  -s -startcmd "node dist/server.js" \
  -allowedcmd "node,npm,pm2"

── SSHFS ─────────────────────────────────────────────────────────
# SSHFS with default SSH key (~/.ssh/id_rsa)
gadirpull -r sshfs://user@server.com/remote/path

# SSHFS with a dedicated deploy key
gadirpull -r sshfs://user@192.168.1.100/var/www -sshkey /home/user/.ssh/deploy_key

# SSHFS — build Docker image after sync
gadirpull -r sshfs://builder@buildserver.internal/builds \
  -buildcmd "docker compose build" \
  -s -startcmd "docker compose up"

# SSHFS with gunicorn service + command whitelist
gadirpull -r sshfs://deployer@server.com/app -c 10 -b nightbuild \
  -s -startcmd "gunicorn app:application" \
  -allowedcmd "gunicorn,python,nginx"

── FTP / FTPS ────────────────────────────────────────────────────
# FTP anonymous access
gadirpull -r ftp://ftp.example.com/pub/files

# FTP with credentials
gadirpull -r ftp://example.com/uploads -user myuser -token mypassword

# FTPS (FTP over TLS)
gadirpull -r ftps://secure.server.com/data -user secureuser -token securepass

# FTP — credentials embedded in URL
gadirpull -r ftp://user:pass@ftp.server.com/directory

# FTP — apply patches after sync
gadirpull -r ftp://updates.server.com/patches -c 10 -b master \
  -buildcmd "./apply-patches.sh" \
  -s -startcmd "systemctl reload service"

# FTP with local copy fallback (auto if curlftpfs unavailable)
gadirpull -r ftp://backup.server.com/archives
# Watch any local non-Git directory (file:// protocol)
gadirpull -r file:///path/to/source/directory

# Watch application assets directory
gadirpull -r file:///var/www/html/assets

# Watch with fast 10-second interval and branch label
gadirpull -r file:///home/user/myapp -c 10 -b 13.x \
  -buildcmd "npm install" \
  -startcmd "npm start" \
  -allowedcmd "node,npm"

# Watch + build command + systemd service
gadirpull -r file:///home/user/myapp \
  -buildcmd "npm install" \
  -s -startcmd "npm start"

# Watch /opt/app with PHP service + command whitelist
gadirpull -r file:///opt/app \
  -s -startcmd "php artisan serve" \
  -allowedcmd "php,node,npm"

# Watch config dir and sync every 10 seconds
gadirpull -r file:///etc/app/config -c 10 -b master \
  -s -startcmd "./app" \
  -envencrypt ".env,secrets.json"

# Watch legacy app directory, block network tools
gadirpull -r file:///var/www/legacy-app \
  -s -startcmd "apache2 -DFOREGROUND" \
  -disallowedcmd "curl,wget,telnet,nc"
── Domain modes ──────────────────────────────────────────────────
# Catch-all mode — serve at http://YOUR_IP/repo-name/ (default, good for multiple apps)
gadirpull -r https://github.com/user/webapp.git -proxy nginx

# Root domain — serve at http://example.com/
gadirpull -r repo -proxy nginx -proxydomain example.com

# Sub-path mode — serve at http://example.com/repo-name/
gadirpull -r repo -proxy nginx -proxydomain "example.com#"

── Static file serving ───────────────────────────────────────────
# Serve static files from repo root (no backend service needed)
gadirpull -r repo -proxy nginx -proxystaticpath "index.html,index.htm"

# Serve PHP static site with index.php fallback
gadirpull -r repo -proxy nginx -proxystaticpath "index.html,index.php"

# Serve from an absolute path outside the repo
gadirpull -r repo -proxy nginx -proxystaticpath /var/www/mysite

── SSL ───────────────────────────────────────────────────────────
# Manual SSL — place certs at /etc/nginx/ssl/example.com/
gadirpull -r repo -proxy nginx -proxydomain example.com -proxyssl true

# Auto SSL via Let's Encrypt Certbot (requires real domain + port 80 open)
gadirpull -r repo -proxy nginx -proxydomain example.com -proxyssl certbot

# Let's Encrypt + 30-day static asset caching
gadirpull -r repo -proxy nginx \
  -proxydomain example.com \
  -proxyssl certbot \
  -proxycache

── Other proxy servers ───────────────────────────────────────────
# Apache
gadirpull -r repo -proxy apache -proxydomain example.com

# Traefik
gadirpull -r repo -proxy traefik -proxydomain example.com -proxyssl certbot

# HAProxy
gadirpull -r repo -proxy haproxy -proxydomain example.com

── Interactive wizard ────────────────────────────────────────────
# Launch wizard for a specific repo
gadirpull -r repo -manageproxy

# Launch wizard for the gadirpull daemon itself
gadirpull -manageproxy
── Node.js full auto-deploy ──────────────────────────────────────
cd /var/www && gadirpull -r https://github.com/company/webapp.git \
  -b production \
  -s -startcmd "node server.js" \
  -buildcmd "npm install && npm run build" \
  -createfile text -filename .env -text "NODE_ENV=production\nPORT=4000"

── Node.js with webhook + security restrictions ──────────────────
gadirpull -r https://github.com/user/express-app.git \
  -buildcmd "gadirpull-tester node:test node:build" \
  -startcmd "node server.js" \
  -allowedcmd "npm,node" \
  -s -c webhook

── Docker microservices stack ────────────────────────────────────
cd /opt/services

# API Gateway
gadirpull -r https://github.com/company/gateway.git \
  -s -startcmd "docker-compose up -d gateway"

# Auth Service
gadirpull -r https://github.com/company/auth.git \
  -s -startcmd "docker-compose up -d auth"

# Background Worker
gadirpull -r https://github.com/company/worker.git \
  -s -startcmd "docker-compose up -d worker"

── Static site + nginx reload ────────────────────────────────────
cd /var/www/html && gadirpull -r https://github.com/company/website.git \
  -b main \
  -buildcmd "chown -R www-data:www-data . && systemctl reload nginx"

── Go API with tests, build, version tag ─────────────────────────
gadirpull -r https://github.com/company/go-api.git \
  -buildcmd "go test ./... && go build -o api-server && systemctl restart go-api" \
  -createfile text -filename .version -text "v1.0.0"

── Python API with internal tester ───────────────────────────────
gadirpull -r https://github.com/company/python-api.git \
  -buildcmd "gadirpull-tester python" \
  -s -startcmd "gunicorn app:app --bind 0.0.0.0:5000"

── Encrypted secrets + auth service ──────────────────────────────
gadirpull -r https://github.com/company/auth.git \
  -s -startcmd "node server" \
  -buildcmd "npm install && mkdir foldername" \
  -allowedcmd "node,npm,mkdir" \
  -envencrypt "myfile.env,myfile.txt,myfile1.cert"

── SMB build server → deploy ─────────────────────────────────────
gadirpull -r smb://buildserver/releases -b main \
  -buildcmd "npm ci && npm run build" \
  -s -startcmd "node dist/server.js" \
  -allowedcmd "node,npm,pm2"
── Command blacklist (block dangerous binaries) ──────────────────
# Block network exfiltration tools for web apps
gadirpull -r https://github.com/user/app.git -s -startcmd "npm start" \
  -disallowedcmd "curl,wget,nc,telnet,ssh,scp,sftp"

# Block shell access — prevent arbitrary code execution
gadirpull -r https://github.com/user/app.git -s -startcmd "node server.js" \
  -disallowedcmd "bash,sh,dash,zsh,su,sudo"

# Block package managers to prevent tampering (dev servers)
gadirpull -r https://github.com/user/app.git -s -startcmd "node server.js" \
  -disallowedcmd "apt,apt-get,dnf,yum,pacman,dpkg,rpm,gcc,make"

# Block process manipulation (microservices)
gadirpull -r https://github.com/user/worker.git -s -startcmd "node worker.js" \
  -disallowedcmd "kill,pkill,killall,nohup,screen,tmux"

── Command whitelist (strict allow-only mode) ────────────────────
# Only node and npm are allowed — everything else is blocked
gadirpull -r https://github.com/company/auth.git -s -startcmd "node server" \
  -allowedcmd "node,npm"

# PHP service — only php and composer
gadirpull -r https://github.com/user/laravel-app.git -s -startcmd "php artisan serve" \
  -allowedcmd "php,composer"

# High-security env — only whitelist your app binary
gadirpull -r https://github.com/company/secure-api.git -s -startcmd "./api" \
  -allowedcmd "/opt/app/bin/app" \
  -disallowedcmd "curl,wget,nc,ssh,rm,chmod,chown,kill,pkill"

── noexecpath — block execution in upload/public dirs ────────────
# Prevents uploaded files from being executed as scripts
gadirpull -r https://github.com/user/app.git -s -startcmd "node server.js" \
  -allowedcmd "node,npm" \
  -noexecpath "public,uploads,tmp,storage"

── NFS + SMB with command restrictions ───────────────────────────
# NFS mount + block network pivoting tools
gadirpull -r nfs://192.168.1.100/exports/app \
  -s -startcmd "python3 app.py" \
  -disallowedcmd "curl,wget,nc,ssh"

# SMB share — whitelist + blacklist combined (different binaries)
gadirpull -r smb://server/share/app \
  -s -startcmd "./start.sh" \
  -allowedcmd "./start.sh,node" \
  -disallowedcmd "rm,chmod,sudo"

── What NOT to do ────────────────────────────────────────────────
# ✗ Wildcard defeats the purpose
-allowedcmd "*"

# ✗ Allowing shells enables arbitrary execution
-allowedcmd "sh,bash,dash"

# ✗ Same binary in both lists → error: "Command cannot be both allowed and disallowed"
gadirpull -r repo -allowedcmd "node,npm" -disallowedcmd "node,curl"  # FAILS
── Starting the daemon ───────────────────────────────────────────
# Foreground mode — useful for testing, Ctrl+C to stop
sudo gadirpull -d

# Bind to localhost only (default — dashboard not accessible from outside)
sudo gadirpull -d -host 127.0.0.1

# Expose dashboard on all interfaces (access from network)
sudo gadirpull -d -host 0.0.0.0

# Custom port (default is 8445)
sudo gadirpull -d -host 0.0.0.0 -port 9000

# Start with custom folders config
sudo gadirpull -d -f /etc/myconfig/folders.txt

# Enable webhook API endpoint — MUST start daemon with -webhook before adding webhook repos
sudo gadirpull -d -webhook

── Systemd service management ────────────────────────────────────
# Create systemd service (interactive — prompts for auto-start on boot)
sudo gadirpull --service

# Remove systemd service and clean up config (same command, interactive)
sudo gadirpull --service

# Check daemon service status
sudo systemctl status gadirpull-daemon

# Restart daemon (applies after config changes)
sudo systemctl restart gadirpull-daemon

# Follow live daemon logs
sudo journalctl -u gadirpull-daemon -f

# Stop the daemon
sudo systemctl stop gadirpull-daemon

── Open the dashboard ────────────────────────────────────────────
# Local machine
xdg-open http://localhost:8445

# Remote server (replace with your server IP)
xdg-open http://192.168.1.50:8445

# Dashboard login uses PAM (your Linux system username + password)
Security

Defense in depth

Every layer is hardened — from authentication to runtime service isolation.

Auth & Sessions

  • PAM authentication for web dashboard
  • Rate limiting: 3 attempts per 20 seconds
  • Session timeout after 10 minutes inactivity
  • Session persistence across daemon restarts

Command Isolation

  • Whitelist with -allowedcmd to restrict binaries
  • Blacklist with -disallowedcmd for dangerous commands
  • Block exec in upload/public dirs with -noexecpath
  • systemd-run isolation for all build/start commands

Credential Protection

  • systemd-creds encryption for sensitive files
  • Credentials decrypted to memory only at runtime
  • 0600 permissions on credential storage
  • Auto-cleanup on repository deletion

Service Hardening

  • ProtectSystem=strict (read-only root filesystem)
  • Private /tmp per service
  • Memory and CPU quota limits (-memlimit, -cpulimit)
  • Hardware-level credential locking support

Internal test & build runner

Automatically detects and executes appropriate test/build commands for your programming language. Use as -buildcmd "gadirpull-tester ..."

Supported Languages: node, node-yarn, node-pnpm, python, python-uv, go, rust, java, java-gradle, php, ruby, dotnet, elixir, swift, kotlin, dart, flutter, c, cpp

Node.jsnpm / yarn / pnpm
Pythonpip / uv
Gogo test/build
Rustcargo
JavaMaven/Gradle
PHPComposer
Rubybundler
.NETdotnet
Elixirmix
Swiftswift build
Kotlingradle
Flutterflutter test
C / C++make / cmake

Gadirpull-tester examples

# Add repository with tester as build command
gadirpull -r https://github.com/user/node-app.git -buildcmd "gadirpull-tester node" -startcmd "node server.js" -s

# Update existing repository build command
gadirpull -r /path/to/repo -buildcmd "gadirpull-tester node go"

# Block dangerous commands only (disallowedcmd)
gadirpull -r https://github.com/user/app.git -buildcmd "gadirpull-tester node" -disallowedcmd "curl,wget,rm,chmod"

# Strict whitelist (allowedcmd)
gadirpull -r https://github.com/user/app.git -buildcmd "gadirpull-tester go" -allowedcmd "npm,node"

# Node.js app with testing, building, and security
gadirpull -r https://github.com/user/express-app.git -buildcmd "gadirpull-tester node:test node:build" -startcmd "node server.js" -allowedcmd "npm,node" -s -c webhook

Multi-Language Test & Build

# Test with internal build using :build (node only)
gadirpull -r https://github.com/user/app.git -buildcmd "gadirpull-tester node:build" -startcmd "node server.js" -s

# Multi test and build: test+build for node, test only for go
gadirpull -r https://github.com/user/app.git -buildcmd "gadirpull-tester node:build go" -startcmd "node server.js"

# Multi test and build: test+build for both node and go
gadirpull -r https://github.com/user/app.git -buildcmd "gadirpull-tester node:build go:build" -startcmd "node server.js"

Custom Commands with -- separator

# Run custom command if test succeeds
gadirpull -r https://github.com/user/app.git -buildcmd "gadirpull-tester node --npm install @latest" -startcmd "node server.js"

# Multi test/build then run custom command
gadirpull -r https://github.com/user/app.git -buildcmd "gadirpull-tester node:build go:build --npm install @latest" -startcmd "node server.js"

# Run builds regardless of test failures (|| true)
gadirpull -r repo -buildcmd "gadirpull-tester node:test node:build -- || true"

Troubleshooting: Build/Test Failures

Issue: test/build command fails with exit code

  • Check if build script exists in package.json, composer.json, Cargo.toml, etc.
  • Example package.json: { "scripts": { "test": "jest", "build": "webpack" } }
  • Tester automatically looks for standard scripts: test, build, ci, check
  • Use -- to provide fallback or ignore failures with || true
  • Verify language runtime is installed (node, go, python, etc.)
# Example: Check package.json scripts
cat package.json | grep -A5 '"scripts"'

# If no build script exists, create one or use inline command
gadirpull -r repo -buildcmd "gadirpull-tester node:test --npm run custom-build"