Zero-downtime Docker deploys with health checks
A small bash script that pulls, health-checks, and rolls back automatically — no docker-rollout, no Kubernetes, just bash.
Zero-downtime Docker deploys with health checks
I don’t need Kubernetes for a 3-node homelab. But I do want zero-downtime deploys. Here’s the bash script I use — pulls new image, swaps container atomically, rolls back if the new container fails health check.
The script
#!/bin/bash
set -euo pipefail
SERVICE="${1:?usage: deploy.sh <service> <image>}"
IMAGE="${2:?usage: deploy.sh <service> <image>}"
COMPOSE_DIR="/srv/compose/${SERVICE}"
HEALTH_URL="${HEALTH_URL:-http://localhost:8080/health}"
OLD_CONTAINER="${SERVICE}_app_1"
cd "$COMPOSE_DIR"
# Save current image for rollback
CURRENT=$(docker inspect --format='{{.Image}}' "$OLD_CONTAINER" 2>/dev/null || echo "")
echo "▶ Pulling $IMAGE"
docker pull "$IMAGE"
# Update image in compose and start new container alongside old
echo "▶ Starting new container"
IMAGE="$IMAGE" docker compose up -d --no-deps --scale app=2 app
# Wait for new container to be healthy
echo "▶ Waiting for health check"
NEW_CONTAINER="${SERVICE}_app_2"
RETRIES=30
until docker inspect --format='{{.State.Health.Status}}' "$NEW_CONTAINER" 2>/dev/null | grep -q healthy; do
RETRIES=$((RETRIES-1))
if [ $RETRIES -le 0 ]; then
echo "✗ Health check failed, rolling back"
docker compose up -d --no-deps --scale app=1 app
exit 1
fi
sleep 2
done
# Stop old container
echo "▶ Stopping old container"
docker compose up -d --no-deps --scale app=1 app
echo "✓ Deployed $SERVICE"
How to use
./deploy.sh myapp myuser/myapp:v1.2.3
Why not docker-rollout / kubectl?
- Simpler: One file, ~30 lines, no Go binary
- No state: Stateless nodes can run this without a cluster manager
- Rollback included: Keeps old container until health check passes
- Auditable: Plain bash, every step is visible
Limitations (be honest)
- Single-node only (fine for my homelab, not for prod at scale)
- No blue/green across multiple hosts
- Health check is HTTP-only — for TCP services you’d want to extend it
For anything bigger, use Kubernetes. For a homelab or a single production host, this is enough.