Files
petfeed/docker/rolling-deploy.sh
admin 1b83bb9665 docs: update README, add session handoff, fix deploy-script executable bit
README: document today's shipped work (story reactions/comments, per-pet
insights dashboard, DESIGN.md/PRODUCT.md design system, admin panel visual
pass) in "What's Shipped" and the admin panel section.

docker/rolling-deploy.sh and start.sh were tracked as 100644 (no executable
bit) since this repo is worked from Windows, which never records it — every
fresh git pull onto the Linux NAS made them non-executable again. Fixed via
git update-index --chmod=+x so this doesn't recur.
2026-08-25 19:24:52 +02:00

60 lines
1.9 KiB
Bash
Executable File

#!/bin/sh
# Zero-downtime rolling deploy for the pawfeed-1/2/3 replicas.
#
# Builds the shared image once, then restarts each replica one at a time,
# waiting for the Docker healthcheck (GET /api/health, see
# docker-compose.yml) to report "healthy" before moving to the next one.
# At every point at least 2 of 3 replicas are serving traffic, so NPM's
# least_conn upstream (docker/npm-upstream.conf) never has fewer than 2
# healthy backends. `docker compose up -d --build` (start.sh) still works
# for a first-time deploy or when downtime doesn't matter — use this
# script for routine deploys against a live site instead.
set -e
cd "$(dirname "$0")"
if [ ! -f .env ]; then
echo "ERROR: docker/.env not found."
echo "Copy .env.example to docker/.env and fill in your values."
exit 1
fi
export SENTRY_RELEASE="$(git -C .. rev-parse --short HEAD)"
REPLICAS="pawfeed-1 pawfeed-2 pawfeed-3"
TIMEOUT_SECS=60
echo "Building shared image..."
docker compose build pawfeed-1
wait_healthy() {
replica="$1"
elapsed=0
while [ "$elapsed" -lt "$TIMEOUT_SECS" ]; do
status="$(docker inspect --format='{{.State.Health.Status}}' "$replica" 2>/dev/null || echo "starting")"
if [ "$status" = "healthy" ]; then
return 0
fi
sleep 2
elapsed=$((elapsed + 2))
done
return 1
}
for replica in $REPLICAS; do
echo "--- Redeploying $replica ---"
docker compose up -d --no-deps "$replica"
echo "Waiting for $replica to report healthy (up to ${TIMEOUT_SECS}s)..."
if wait_healthy "$replica"; then
echo "$replica is healthy."
else
echo "ERROR: $replica did not become healthy within ${TIMEOUT_SECS}s."
echo "Check: docker logs $replica"
echo "Aborting before touching the remaining replicas — the ones already"
echo "redeployed keep running, the rest are untouched and still on the old image."
exit 1
fi
done
echo "Rolling deploy complete — all 3 replicas updated with zero downtime."