Some checks failed
- deploy.sh writes .build-info with commit SHA and timestamp after git pull - /health endpoint now returns version, commit, and deployed_at fields - Admin sidebar footer shows version and commit SHA - Hetzner docs updated: runner --config flag, swap, and runner timeout Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
97 lines
3.6 KiB
Bash
Executable File
97 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# Orion Production Deploy Script
|
|
# =============================================================================
|
|
# Usage: cd ~/apps/orion && bash scripts/deploy.sh
|
|
#
|
|
# Called by Gitea Actions CD pipeline (appleboy/ssh-action) or manually.
|
|
#
|
|
# Exit codes:
|
|
# 0 — success
|
|
# 1 — git pull failed
|
|
# 2 — docker compose build/up failed
|
|
# 3 — alembic migration failed
|
|
# 4 — health check failed
|
|
# =============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
COMPOSE="docker compose --profile full"
|
|
HEALTH_URL="http://localhost:8001/health"
|
|
HEALTH_RETRIES=12
|
|
HEALTH_INTERVAL=5
|
|
|
|
log() { echo "[deploy] $(date '+%H:%M:%S') $*"; }
|
|
|
|
# ── 1. Pull latest code (stash local changes like .env) ─────────────────────
|
|
log "Stashing local changes …"
|
|
git stash --include-untracked --quiet || true
|
|
|
|
log "Pulling latest code …"
|
|
if ! git pull --ff-only; then
|
|
log "ERROR: git pull failed"
|
|
git stash pop --quiet 2>/dev/null || true
|
|
exit 1
|
|
fi
|
|
|
|
log "Restoring local changes …"
|
|
git stash pop --quiet 2>/dev/null || true
|
|
|
|
# ── 1b. Write build info ─────────────────────────────────────────────────────
|
|
log "Writing build info …"
|
|
printf '{"commit":"%s","deployed_at":"%s"}\n' \
|
|
"$(git rev-parse --short=8 HEAD)" \
|
|
"$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
> .build-info
|
|
|
|
# ── 2. Rebuild and restart containers ────────────────────────────────────────
|
|
log "Rebuilding containers …"
|
|
if ! $COMPOSE up -d --build; then
|
|
log "ERROR: docker compose up failed"
|
|
exit 2
|
|
fi
|
|
|
|
# ── 3. Wait for DB to be healthy before running migrations ──────────────────
|
|
log "Waiting for database to be healthy …"
|
|
for i in $(seq 1 12); do
|
|
if $COMPOSE exec -T db pg_isready -U orion_user -d orion_db > /dev/null 2>&1; then
|
|
log "Database is ready (attempt $i/12)"
|
|
break
|
|
fi
|
|
if [ "$i" -eq 12 ]; then
|
|
log "ERROR: database not ready after 60s"
|
|
exit 3
|
|
fi
|
|
sleep 5
|
|
done
|
|
|
|
# ── 4. Run database migrations ───────────────────────────────────────────────
|
|
log "Running database migrations …"
|
|
if ! $COMPOSE exec -T -e PYTHONPATH=/app api python -m alembic upgrade heads; then
|
|
log "ERROR: alembic migration failed"
|
|
exit 3
|
|
fi
|
|
|
|
# ── 5. Health check with retries ─────────────────────────────────────────────
|
|
log "Waiting for health check ($HEALTH_URL) …"
|
|
for i in $(seq 1 "$HEALTH_RETRIES"); do
|
|
if curl -sf "$HEALTH_URL" > /dev/null 2>&1; then
|
|
log "Health check passed (attempt $i/$HEALTH_RETRIES)"
|
|
break
|
|
fi
|
|
log "Health check attempt $i/$HEALTH_RETRIES failed, retrying in ${HEALTH_INTERVAL}s …"
|
|
sleep "$HEALTH_INTERVAL"
|
|
done
|
|
|
|
if ! curl -sf "$HEALTH_URL" > /dev/null 2>&1; then
|
|
log "ERROR: health check failed after $HEALTH_RETRIES attempts"
|
|
exit 4
|
|
fi
|
|
|
|
# ── 6. Clean up old Docker images ───────────────────────────────────────────
|
|
log "Pruning unused Docker images …"
|
|
docker image prune -f --filter "until=72h" > /dev/null 2>&1 || true
|
|
|
|
log "Deploy complete."
|
|
exit 0
|