Zero-downtime deployment orchestration plugin for Docker Compose with rolling, blue-green, and canary strategies.
Important
docker ztd requires a traefik service in your docker-compose.yml.
The plugin will not work without Traefik present in the Compose project.
docker ztd updates a running Compose service without dropping traffic:
- scales service to additional replicas
- waits for new containers to become ready
- switches Traefik dynamic config to new container IDs
- removes old containers after a drain wait
For complete, ready-to-run helloworld examples and deployment notes, see:
docker-compose-deployments-examples
The Go implementation is the recommended path for most users.
curl -fsSL https://raw.githubusercontent.com/ku9nov/docker-compose-ztd-plugin/main/scripts/install-docker-ztd-go.sh | bashdocker ztd -f docker-compose.yml up -d# Rolling (default)
docker ztd -f docker-compose.yml api
# Blue-green
docker ztd -f docker-compose.yml --strategy=blue-green --host-mode=green.example.com api
docker ztd -f docker-compose.yml --strategy=blue-green api switch
# Canary
docker ztd -f docker-compose.yml --strategy=canary --weight=10 api
docker ztd -f docker-compose.yml --strategy=canary --weight=70 api- Docker CLI
- Traefik service in the same Compose project (
traefik) - Compose support:
docker compose(preferred), ordocker-compose(fallback)
Always pass -f docker-compose.yml (or your custom compose file path).
docker ztd -f docker-compose.yml [OPTIONS] SERVICE
docker ztd -f docker-compose.yml [OPTIONS] SERVICE ACTION
docker ztd auto-cleanup-rundocker ztd -f docker-compose.yml apidocker ztd -f docker-compose.yml --strategy=blue-green --host-mode=green.example.com api
docker ztd -f docker-compose.yml --strategy=blue-green api switch
docker ztd -f docker-compose.yml --strategy=blue-green --auto-cleanup=10m api switch
docker ztd -f docker-compose.yml --strategy=blue-green api cleanupdocker ztd -f docker-compose.yml --strategy=canary --weight=10 api
docker ztd -f docker-compose.yml --strategy=canary --weight=70 api
docker ztd -f docker-compose.yml --strategy=canary api rollback
docker ztd -f docker-compose.yml --strategy=canary --auto-cleanup=10m api rollback
docker ztd -f docker-compose.yml --strategy=canary api cleanupdocker ztd auto-cleanup-runswitch(blue-green only): switch active traffic between blue and greenrollback(canary only): route100%traffic to old containerscleanup(blue-green/canary): remove inactive containers and clear stateauto-cleanup-run: process overdue cleanup deadlines from state files
-h, --help-f, --file FILE--env-file FILE-t, --timeout N-w, --wait N--wait-after-healthy N--strategy TYPE(rollingdefault,blue-green,canary)--proxy TYPE(traefikdefault,nginx-proxy)--traefik-conf FILE
--host-mode VALUE(route by host, HTTP Host / TCP HostSNI)--headers-mode HEADER=VALUE(HTTP only, example:X-Env=green)--cookies-mode COOKIE=VALUE(HTTP only, example:env=green)--ip-mode VALUE(route by client IP CIDR, HTTP/TCP)--to COLOR(switchaction only,blue|green)
--weight N(default:10)
--auto-cleanup DURATION(switch/rollbackactions only, example:10m)
--analyze--metrics-url URL--analyze-window DURATION--analyze-interval DURATION--min-requests N--max-5xx-ratio N--max-4xx-ratio N(-1disables)--max-mean-latency-ms N(-1disables)
State files are stored at:
.ztd/state/<compose_project>--<service>.json
- stores service, strategy, blue/green container IDs, active color, and optional cleanup deadline
- overdue
cleanupAtentries are processed as a safety net on CLI startup - overdue entries can also be processed by scheduler via
auto-cleanup-run
- stores service, strategy, old/new container IDs, and current canary weight
cleanupis allowed only for terminal canary states:- new=
100-> remove old - new=
0-> remove new - intermediate weights are rejected to preserve rollback safety
- new=
traefik.enabletraefik.http.routers.<name>.ruletraefik.http.services.<name>.loadbalancer.server.porttraefik.http.services.<name>.loadbalancer.healthCheck.pathtraefik.http.services.<name>.loadbalancer.healthCheck.intervaltraefik.http.services.<name>.loadbalancer.healthCheck.timeouttraefik.http.services.<name>.loadbalancer.healthCheck.schemetraefik.http.services.<name>.loadbalancer.healthCheck.modetraefik.http.services.<name>.loadbalancer.healthCheck.hostnametraefik.http.services.<name>.loadbalancer.healthCheck.porttraefik.http.services.<name>.loadbalancer.healthCheck.headers.<header>traefik.http.services.<name>.loadbalancer.healthCheck.followRedirectstraefik.http.services.<name>.loadbalancer.healthCheck.methodtraefik.http.services.<name>.loadbalancer.healthCheck.statustraefik.tcp.routers.<name>.ruletraefik.tcp.routers.<name>.entrypointstraefik.tcp.routers.<name>.tlstraefik.tcp.services.<name>.loadbalancer.server.port
--auto-cleanup writes cleanup deadlines into state files. To execute cleanup at those deadlines, run docker ztd auto-cleanup-run periodically.
By default, project registry is stored at ~/.ztd/registry/projects.json for the current OS user. You can override it with ZTD_REGISTRY_PATH.
Auto-cleanup is user-scoped. If different users run docker ztd for different projects, each user needs their own scheduler.
Service unit (/etc/systemd/system/ztd-auto-cleanup.service):
[Unit]
Description=Run docker ztd overdue auto-cleanup
After=docker.service
Wants=docker.service
[Service]
Type=oneshot
User=deploy
Environment=ZTD_REGISTRY_PATH=~/.ztd/registry/projects.json
ExecStart=/usr/bin/docker ztd auto-cleanup-runTimer unit (/etc/systemd/system/ztd-auto-cleanup.timer):
[Unit]
Description=Schedule docker ztd overdue auto-cleanup
[Timer]
OnCalendar=*:0/1
Persistent=true
Unit=ztd-auto-cleanup.service
[Install]
WantedBy=timers.targetEnable:
sudo systemctl daemon-reload
sudo systemctl enable --now ztd-auto-cleanup.timer
sudo systemctl status ztd-auto-cleanup.timerLogs:
journalctl -u ztd-auto-cleanup.service -fTo avoid overlapping runs, the command uses a non-blocking file lock at .ztd/state/.auto-cleanup.lock.
For hosts without systemd:
*/5 * * * * /usr/bin/docker ztd auto-cleanup-run >> /var/log/ztd-auto-cleanup.log 2>&1Bash implementation is still available for legacy environments, but Go implementation is recommended for new setups.
Install:
curl -fsSL https://gist.githubusercontent.com/ku9nov/f76d2b7f65fa266a17c89e0a50880479/raw/9182ae94d16bea270a4228dd17be16f05e156041/install-docker-ztd.sh | bashDependencies:
jqyq
- Avoid
container_nameand fixed hostportson services that need multi-replica rollout. nginx-proxymode is not implemented yet.