olivas/deploy.sh
Vadym Samoilenko 2c7b89670d Fix alembic PYTHONPATH in deploy script
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 13:29:11 +00:00

142 lines
4.9 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
# =============================================================================
# OliVAS Production Deploy Script
# Idempotent — safe to run for initial deploy and subsequent updates
# =============================================================================
REPO_DIR=/opt/olivas
WEB_DIR=/var/www/html/olivas
COMPOSE="docker compose -f docker-compose.yml -f docker-compose.prod.yml"
# ---------------------------------------------------------------------------
# Color helpers
# ---------------------------------------------------------------------------
info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[WARN]\033[0m %s\n' "$*"; }
error() { printf '\033[1;31m[ERROR]\033[0m %s\n' "$*"; }
success() { printf '\033[1;32m[OK]\033[0m %s\n' "$*"; }
# ---------------------------------------------------------------------------
# 1. Preflight checks
# ---------------------------------------------------------------------------
if ! command -v docker &>/dev/null; then
error "docker is not installed."
exit 1
fi
if ! docker compose version &>/dev/null; then
error "docker compose plugin is not available."
exit 1
fi
# ---------------------------------------------------------------------------
# 2. Pull latest code
# ---------------------------------------------------------------------------
cd "$REPO_DIR"
info "Pulling latest code..."
git pull --ff-only origin main
COMMIT=$(git rev-parse --short HEAD)
success "At commit $COMMIT"
# ---------------------------------------------------------------------------
# 3. Handle .env
# ---------------------------------------------------------------------------
if [[ ! -f .env ]]; then
cp .env.example .env
warn ".env was created from .env.example."
warn "Edit /opt/olivas/.env with production values, then re-run this script."
exit 0
fi
info "Loading .env..."
set -a
# shellcheck disable=SC1091
source .env
set +a
# ---------------------------------------------------------------------------
# 4. Build backend Docker image
# ---------------------------------------------------------------------------
info "Building backend image..."
$COMPOSE build backend
# ---------------------------------------------------------------------------
# 5. Start postgres and wait for it to be healthy
# ---------------------------------------------------------------------------
info "Starting postgres..."
$COMPOSE up -d postgres
info "Waiting for postgres to be ready..."
for i in $(seq 1 30); do
if $COMPOSE exec postgres pg_isready -U olivas &>/dev/null; then
success "Postgres is ready."
break
fi
if [[ $i -eq 30 ]]; then
error "Postgres did not become ready within 30 seconds."
exit 1
fi
sleep 1
done
# ---------------------------------------------------------------------------
# 6. Run database migrations
# ---------------------------------------------------------------------------
info "Starting backend for migrations..."
$COMPOSE up -d backend
info "Running database migrations..."
$COMPOSE exec -e PYTHONPATH=/app backend alembic -c alembic.ini upgrade head
success "Migrations complete."
# ---------------------------------------------------------------------------
# 7. Restart backend (pick up new code/env)
# ---------------------------------------------------------------------------
info "Restarting backend..."
$COMPOSE up -d --force-recreate backend
success "Backend restarted."
# ---------------------------------------------------------------------------
# 8. Build frontend in a temporary Docker container
# ---------------------------------------------------------------------------
info "Building frontend..."
docker run --rm \
-v "$REPO_DIR/frontend:/app" \
-w /app \
-e VITE_AZURE_TENANT_ID \
-e VITE_AZURE_CLIENT_ID \
-e VITE_AZURE_REDIRECT_URI \
node:20-alpine \
sh -c "npm ci --prefer-offline && npm run build"
success "Frontend built."
# ---------------------------------------------------------------------------
# 9. Deploy frontend to web directory
# ---------------------------------------------------------------------------
info "Deploying frontend to $WEB_DIR..."
mkdir -p "$WEB_DIR"
rm -rf "${WEB_DIR:?}"/*
cp -r "$REPO_DIR/frontend/dist/"* "$WEB_DIR/"
chmod -R a+rX "$WEB_DIR"
success "Frontend deployed."
# ---------------------------------------------------------------------------
# 10. Health check
# ---------------------------------------------------------------------------
info "Waiting for backend health check..."
sleep 3
if curl -sf http://localhost:8000/api/health > /dev/null 2>&1; then
success "Backend health check passed."
else
warn "Backend health check failed — it may still be starting up."
fi
# ---------------------------------------------------------------------------
# 11. Summary
# ---------------------------------------------------------------------------
echo ""
success "Deploy complete"
info "Commit: $COMMIT"
info "Timestamp: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"