Add a named volume for Redis so queue data survives container restarts. Add deploy-backend-safe.sh that rebuilds and recreates only app/worker containers while leaving db and redis untouched, preserving the queue. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
94 lines
2.6 KiB
Bash
Executable file
94 lines
2.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
#
|
|
# Redeploy backend services with latest code WITHOUT destroying
|
|
# the Redis queue (or Postgres data). Rebuilds and recreates only
|
|
# the app/worker containers, leaving db and redis untouched.
|
|
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
COMPOSE_FILE="$ROOT_DIR/backend/docker-compose.yml"
|
|
ENV_FILE="$ROOT_DIR/backend/.env"
|
|
|
|
APP_SERVICES="web celery_worker_default celery_worker_video celery_beat"
|
|
|
|
# --- Preflight checks ---
|
|
|
|
if [ ! -d "$ROOT_DIR/.git" ]; then
|
|
echo "Error: run this script from the repo root (expected .git here)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "Error: docker is required but not found in PATH." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! docker compose version >/dev/null 2>&1; then
|
|
echo "Error: docker compose is required but not available." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$ENV_FILE" ]; then
|
|
echo "Error: environment variables not found at $ENV_FILE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$COMPOSE_FILE" ]; then
|
|
echo "Error: docker compose file not found at $COMPOSE_FILE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# --- Deploy ---
|
|
|
|
echo ""
|
|
echo "Pulling latest code..."
|
|
git -C "$ROOT_DIR" pull
|
|
|
|
echo ""
|
|
echo "Ensuring db and redis are running..."
|
|
docker compose -f "$COMPOSE_FILE" up -d db redis
|
|
|
|
echo ""
|
|
echo "Building app services (no cache)..."
|
|
docker compose -f "$COMPOSE_FILE" build --no-cache $APP_SERVICES
|
|
|
|
echo ""
|
|
echo "Recreating app services (redis & db untouched)..."
|
|
docker compose -f "$COMPOSE_FILE" up -d --force-recreate --no-deps $APP_SERVICES
|
|
|
|
echo ""
|
|
echo "Waiting for database to be healthy..."
|
|
MAX_ATTEMPTS=30
|
|
ATTEMPT=0
|
|
|
|
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
|
|
if docker compose -f "$COMPOSE_FILE" exec -T db pg_isready -U pah -d pah >/dev/null 2>&1; then
|
|
echo "Database is ready."
|
|
break
|
|
fi
|
|
|
|
ATTEMPT=$((ATTEMPT + 1))
|
|
|
|
if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then
|
|
echo "Error: database did not become healthy after $MAX_ATTEMPTS attempts." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Waiting for database... (attempt $ATTEMPT/$MAX_ATTEMPTS)"
|
|
sleep 2
|
|
done
|
|
|
|
echo ""
|
|
echo "Running database migrations..."
|
|
docker compose -f "$COMPOSE_FILE" exec -T web alembic upgrade head
|
|
|
|
echo ""
|
|
echo "Verifying Redis queue preserved..."
|
|
VIDEO_QUEUE=$(docker compose -f "$COMPOSE_FILE" exec -T redis redis-cli LLEN video 2>/dev/null || echo "?")
|
|
DEFAULT_QUEUE=$(docker compose -f "$COMPOSE_FILE" exec -T redis redis-cli LLEN celery 2>/dev/null || echo "?")
|
|
echo " video queue: $VIDEO_QUEUE tasks"
|
|
echo " default queue: $DEFAULT_QUEUE tasks"
|
|
|
|
echo ""
|
|
echo "Backend deploy complete (queue-safe)."
|