Add idempotent production deploy script and docker-compose override
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2c5e17c7c4
commit
7925264307
2 changed files with 153 additions and 0 deletions
147
deploy.sh
Executable file
147
deploy.sh
Executable file
|
|
@ -0,0 +1,147 @@
|
|||
#!/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 [[ $EUID -ne 0 ]]; then
|
||||
error "This script must be run as root."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
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 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/"
|
||||
chown -R www-data:www-data "$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')"
|
||||
6
docker-compose.prod.yml
Normal file
6
docker-compose.prod.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
services:
|
||||
postgres:
|
||||
ports: !override []
|
||||
restart: unless-stopped
|
||||
backend:
|
||||
restart: unless-stopped
|
||||
Loading…
Add table
Reference in a new issue