#!/usr/bin/env bash # Deploy the full stack to ambrosio. # # Usage: infra/scripts/deploy-erosi.sh # Env: DEPLOY_HOST=ambrosio (override if needed) # DEPLOY_PATH=/opt/colectivo # # First run: # 1. rsyncs repo → ambrosio:/opt/colectivo/ # 2. if .env doesn't exist on server, generates secrets and writes it # 3. patches realm-export.erosi.json with the generated Keycloak client secret # 4. docker compose build + up -d # 5. applies DB migrations # 6. installs the Caddyfile snippet into host Caddy and reloads # # Subsequent runs: rsync + rebuild app + rolling restart. set -euo pipefail DEPLOY_HOST="${DEPLOY_HOST:-ambrosio}" DEPLOY_PATH="${DEPLOY_PATH:-/opt/colectivo}" REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)" echo "==> Deploying to $DEPLOY_HOST:$DEPLOY_PATH" # ── 1. Ensure target dir exists ──────────────────────────────────────────── ssh "$DEPLOY_HOST" "sudo mkdir -p $DEPLOY_PATH && sudo chown \$(id -u):\$(id -g) $DEPLOY_PATH" # ── 2. rsync repo (excluding node_modules / build artefacts / local env) ── rsync -az --delete \ --exclude '.git' \ --exclude 'node_modules' \ --exclude '.svelte-kit' \ --exclude 'apps/web/build' \ --exclude 'apps/web/.vite' \ --exclude '**/*.log' \ --exclude '**/.env' \ --exclude '**/.env.development' \ --exclude '**/.env.local' \ --exclude 'lighthouse-report.html' \ --exclude 'coverage' \ --exclude 'test-results' \ --exclude 'playwright-report' \ "$REPO_ROOT/" "$DEPLOY_HOST:$DEPLOY_PATH/" # ── 3. Bootstrap secrets on first run ────────────────────────────────────── ssh "$DEPLOY_HOST" bash -s << 'REMOTE' set -euo pipefail cd /opt/colectivo if [ ! -f .env ]; then echo "--- First deploy: generating secrets" # JWT triplet (anon + service_role) JWT_OUT=$(bash infra/scripts/rotate-jwt.sh) SUPABASE_JWT_SECRET=$(echo "$JWT_OUT" | awk -F= '/^SUPABASE_JWT_SECRET=/{print substr($0, index($0,$2))}') PUBLIC_SUPABASE_ANON_KEY=$(echo "$JWT_OUT" | awk -F= '/^PUBLIC_SUPABASE_ANON_KEY=/{print substr($0, index($0,$2))}') SUPABASE_SERVICE_ROLE_KEY=$(echo "$JWT_OUT" | awk -F= '/^SUPABASE_SERVICE_ROLE_KEY=/{print substr($0, index($0,$2))}') # Other passwords + keys POSTGRES_PASSWORD=$(openssl rand -hex 24) KEYCLOAK_ADMIN_PASSWORD=$(openssl rand -hex 24) KEYCLOAK_CLIENT_SECRET=$(openssl rand -hex 24) REALTIME_ENC_KEY=$(openssl rand -hex 8) # 16 chars REALTIME_SECRET_KEY_BASE=$(openssl rand -hex 48) # 96 chars cat > .env < /tmp/Caddyfile.new { echo "" echo "$MARKER_START" cat infra/caddy/erosi.Caddyfile echo "$MARKER_END" } >> /tmp/Caddyfile.new sudo mv /tmp/Caddyfile.new /etc/caddy/Caddyfile sudo caddy validate --config /etc/caddy/Caddyfile sudo systemctl reload caddy echo "--- Caddy reloaded" REMOTE echo "==> Deploy complete." echo " App: https://erosi.oier.ovh" echo " Keycloak: https://auth.oier.ovh" echo " Admin pw: ssh $DEPLOY_HOST 'grep KEYCLOAK_ADMIN_PASSWORD $DEPLOY_PATH/.env'"