GitLab CI runs pytest + ruff on master/MRs, then auto-deploys via SSH. Blue-green strategy using Docker Compose profiles with an nginx router on port 5000 for zero-downtime switching between slots. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
77 lines
2.5 KiB
Bash
Executable File
77 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
COMPOSE="docker compose -f docker-compose.prod.yml"
|
|
LIVE_FILE=".live-slot"
|
|
ROUTER_CONF="router/default.conf"
|
|
|
|
# ── Determine slots ─────────────────────────────────────────
|
|
|
|
CURRENT=$(cat "$LIVE_FILE" 2>/dev/null || echo "none")
|
|
|
|
if [ "$CURRENT" = "blue" ]; then
|
|
TARGET="green"
|
|
else
|
|
TARGET="blue"
|
|
fi
|
|
|
|
echo "==> Current: $CURRENT → Deploying: $TARGET"
|
|
|
|
# ── Build ───────────────────────────────────────────────────
|
|
|
|
echo "==> Building $TARGET..."
|
|
$COMPOSE --profile "$TARGET" build
|
|
|
|
# ── Migrate ─────────────────────────────────────────────────
|
|
|
|
echo "==> Running migrations..."
|
|
$COMPOSE --profile "$TARGET" run --rm "${TARGET}-app" \
|
|
python -m padelnomics.migrations.migrate
|
|
|
|
# ── Start & health check ───────────────────────────────────
|
|
|
|
echo "==> Starting $TARGET (waiting for health check)..."
|
|
if ! $COMPOSE --profile "$TARGET" up -d --wait; then
|
|
echo "!!! Health check failed — rolling back"
|
|
$COMPOSE --profile "$TARGET" stop
|
|
exit 1
|
|
fi
|
|
|
|
# ── Switch router ───────────────────────────────────────────
|
|
|
|
echo "==> Switching router to $TARGET..."
|
|
mkdir -p "$(dirname "$ROUTER_CONF")"
|
|
cat > "$ROUTER_CONF" <<NGINX
|
|
upstream app {
|
|
server ${TARGET}-app:5000;
|
|
}
|
|
|
|
server {
|
|
listen 80;
|
|
|
|
location / {
|
|
proxy_pass http://app;
|
|
proxy_set_header Host \$host;
|
|
proxy_set_header X-Real-IP \$remote_addr;
|
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
}
|
|
}
|
|
NGINX
|
|
|
|
# Ensure router is running, then reload
|
|
$COMPOSE up -d router
|
|
$COMPOSE exec router nginx -s reload
|
|
|
|
# ── Stop old slot ───────────────────────────────────────────
|
|
|
|
if [ "$CURRENT" != "none" ]; then
|
|
echo "==> Stopping $CURRENT..."
|
|
$COMPOSE --profile "$CURRENT" stop
|
|
fi
|
|
|
|
# ── Record live slot ────────────────────────────────────────
|
|
|
|
echo "$TARGET" > "$LIVE_FILE"
|
|
echo "==> Deployed $TARGET successfully!"
|