Auto-deploy via Git + Docker Compose¶
This guide shows how to enable automatic deployments on a single Linux host using Git and Docker Compose. It works with cron or systemd timers and focuses on safety: if certain critical files change (e.g., .env or docker-compose.yml), the deployment is blocked to avoid breaking production.
Features¶
- Detects updates in the remote Git branch
- Blocks deployment if critical files changed (configurable via blocklist)
- Builds images using one or more Compose files
- Deploys using
docker compose up -dor restarts services - Supports logs and a file lock to prevent overlapping runs
Files¶
scripts/auto_deploy.sh— main scriptscripts/auto_deploy.conf.example— example configuration to copy and adjustscripts/auto_deploy.blocklist— default glob patterns treated as critical changes
Install¶
- Copy the example config and edit paths and options:
- Ensure the script is executable:
- Make sure the repo is cloned on the host and the configured branch exists (default
main).
Configuration¶
The config is bash-sourced by the script. Key options:
REPO_DIR: absolute path to your repo cloneREMOTE,BRANCH: Git remote and branch to trackAUTO_CHECKOUT: switch toBRANCHautomatically if differentCOMPOSE_FILES: one or multiple compose files, colon-separatedSERVICES: optional space-separated list of services to limit build/deployBUILD_FLAGS: flags forcompose build(e.g.,--pull,--no-cache)DEPLOY_COMMAND:up(default) orrestartUP_FLAGS: flags passed tocompose upwhenDEPLOY_COMMAND=upPRUNE_AFTER:true/falseto prune dangling images after deployCRITICAL_PATHS_FILE: path to blocklist fileCRITICAL_PATHS: comma-separated glob patterns; complements the fileLOG_FILE,LOCK_FILE: where to write logs and lockCOMPOSE_CMD_OVERRIDE: forcedocker-composeif needed
Safety: Critical Changes¶
If any changed file matches the blocklist, deployment is skipped with exit code 10. You can edit scripts/auto_deploy.blocklist or specify extra patterns via CRITICAL_PATHS in the config.
Common critical patterns:
.env*config/**docker-compose*.ymlDockerfile*requirements*.txt,pyproject.toml,poetry.lock
Cron Setup¶
Edit your user crontab with crontab -e and add:
*/5 * * * * /bin/bash -lc 'cd /path/to/your/repo && scripts/auto_deploy.sh -c scripts/auto_deploy.conf >> logs/cron.tail 2>&1'
This runs every 5 minutes. The script itself writes a detailed log to LOG_FILE (configured), and uses a lock file to prevent overlap.
Systemd Timer (alternative)¶
Create /etc/systemd/system/auto-deploy.service:
[Unit]
Description=Auto Deploy Service
After=network-online.target docker.service
Wants=network-online.target
[Service]
Type=oneshot
WorkingDirectory=/path/to/your/repo
Environment=CONFIG_FILE=/path/to/your/repo/scripts/auto_deploy.conf
ExecStart=/bin/bash -lc 'scripts/auto_deploy.sh -c "$CONFIG_FILE"'
Create /etc/systemd/system/auto-deploy.timer:
[Unit]
Description=Run Auto Deploy every 5 minutes
[Timer]
OnBootSec=1min
OnUnitActiveSec=5min
Unit=auto-deploy.service
[Install]
WantedBy=timers.target
Enable and start:
Exit Codes¶
0: No changes or deployment completed successfully10: Critical change detected, deployment skipped1: Error (e.g., unclean working tree, git fetch/pull error, compose missing)
Notes¶
- The script expects a clean working tree and a fast-forwardable branch.
- If the local branch is ahead of remote, the script aborts to avoid force-pushing from automation.
- For legacy environments without
docker compose, setCOMPOSE_CMD_OVERRIDE="docker-compose".