d8d01a5fff
Split the raggr service into raggr-blue (8080) and raggr-green (8081) behind compose profiles, add a /api/health endpoint and container healthcheck, and add scripts/deploy.sh to build the inactive color, wait for it to become healthy, then gracefully stop the old one. Makefile targets resolve the active color automatically. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
49 lines
1.7 KiB
Bash
Executable File
49 lines
1.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# Zero-downtime blue-green deploy.
|
|
#
|
|
# Builds the inactive color, starts it, waits for its healthcheck to pass,
|
|
# then gracefully stops the old color. Caddy health-checks both ports
|
|
# (8080 = blue, 8081 = green) and routes traffic to whichever is healthy,
|
|
# so the swap is invisible to clients.
|
|
#
|
|
# Caveats:
|
|
# - Migrations run on the new container's startup while the old one still
|
|
# serves, so they must be backward-compatible (additive changes only;
|
|
# destructive changes need a two-step deploy).
|
|
# - During the brief overlap both containers run pull-only Obsidian sync
|
|
# against the shared ./obvault mount.
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
running_services=$(docker compose ps --status running --services)
|
|
|
|
if echo "$running_services" | grep -qx "raggr-blue"; then
|
|
OLD=blue NEW=green
|
|
elif echo "$running_services" | grep -qx "raggr-green"; then
|
|
OLD=green NEW=blue
|
|
else
|
|
OLD="" NEW=blue
|
|
fi
|
|
|
|
echo "==> Active: ${OLD:-none} | Deploying: $NEW"
|
|
|
|
echo "==> Building raggr-$NEW..."
|
|
docker compose --profile "$NEW" build "raggr-$NEW"
|
|
|
|
echo "==> Starting raggr-$NEW and waiting for healthy..."
|
|
if ! docker compose --profile "$NEW" up -d --wait "raggr-$NEW"; then
|
|
echo "!! raggr-$NEW failed to become healthy${OLD:+; raggr-$OLD is still serving}" >&2
|
|
docker compose --profile "$NEW" logs --tail 50 "raggr-$NEW" >&2 || true
|
|
docker compose --profile "$NEW" stop -t 5 "raggr-$NEW" || true
|
|
exit 1
|
|
fi
|
|
|
|
if [ -n "$OLD" ]; then
|
|
echo "==> raggr-$NEW healthy; stopping raggr-$OLD (30s grace for in-flight streams)..."
|
|
docker compose --profile "$OLD" stop -t 30 "raggr-$OLD"
|
|
docker compose --profile "$OLD" rm -f "raggr-$OLD"
|
|
fi
|
|
|
|
echo "==> Deploy complete: raggr-$NEW is live"
|