Zero-downtime Docker deploys ด้วย health checks
Bash script เล็ก ๆ ที่ pull, health-check, และ roll back อัตโนมัติ — ไม่ใช้ docker-rollout, ไม่ใช้ Kubernetes แค่ bash
Zero-downtime Docker deploys ด้วย health checks
ผมไม่จำเป็นต้องใช้ Kubernetes สำหรับ homelab 3 nodes แต่ผมอยากได้ zero-downtime deploys นี่คือ bash script ที่ใช้ — pull image ใหม่ สลับ container แบบ atomic roll back ถ้า container ใหม่ health check fail
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}"
OLD_CONTAINER="${SERVICE}_app_1"
cd "$COMPOSE_DIR"
echo "▶ Pulling $IMAGE"
docker pull "$IMAGE"
echo "▶ Starting new container"
IMAGE="$IMAGE" docker compose up -d --no-deps --scale app=2 app
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
echo "▶ Stopping old container"
docker compose up -d --no-deps --scale app=1 app
echo "✓ Deployed $SERVICE"
วิธีใช้
./deploy.sh myapp myuser/myapp:v1.2.3
ทำไมไม่ใช้ docker-rollout / kubectl?
- ง่ายกว่า: ไฟล์เดียว ~30 บรรทัด ไม่มี Go binary
- ไม่มี state: Stateless nodes รันได้โดยไม่ต้องมี cluster manager
- Rollback ในตัว: เก็บ container เก่าไว้จนกว่า health check จะผ่าน
- ตรวจสอบได้: Bash ล้วนทุกขั้นเห็นได้ชัดเจน
ข้อจำกัด (พูดตรง ๆ)
- Single-node เท่านั้น (โอเคสำหรับ homelab ไม่พอสำหรับ prod ที่ใหญ่)
- ไม่มี blue/green ข้ามหลาย hosts
- Health check เป็น HTTP อย่างเดียว — สำหรับ TCP services ต้องขยาย
สำหรับอะไรที่ใหญ่กว่าใช้ Kubernetes สำหรับ homelab หรือ host เดียว อันนี้พอแล้ว