#!/usr/bin/env bash set -euo pipefail # esc deploy script — idempotent, can be re-run safely # Target: Uberspace 8 (serve.uber.space) HOST="serve" SERVICE_DIR="services/esc" STATIC_DIR="/var/www/virtual/serve/html/esc" DB_NAME="esc" PORT=3006 echo "=== celebrate-esc deploy ===" # ── 1. Create database if needed ───────────────────────────────────── echo "→ ensuring database exists..." ssh "$HOST" "createdb -h localhost -p 5433 $DB_NAME 2>/dev/null || true" # ── 2. Build client locally ────────────────────────────────────────── echo "→ building client..." cd packages/client VITE_BASE="/esc/" bun run build cd ../.. # ── 3. Sync server code ───────────────────────────────────────────── echo "→ syncing server to $HOST:~/$SERVICE_DIR/..." ssh "$HOST" "mkdir -p ~/$SERVICE_DIR" rsync -az --delete \ --exclude='node_modules' \ --exclude='.env' \ packages/server/ "$HOST:~/$SERVICE_DIR/server/" rsync -az --delete \ --exclude='node_modules' \ packages/shared/ "$HOST:~/$SERVICE_DIR/shared/" # Copy root workspace files needed for bun install scp package.json "$HOST:~/$SERVICE_DIR/" scp tsconfig.json "$HOST:~/$SERVICE_DIR/" scp bun.lock "$HOST:~/$SERVICE_DIR/" # ── 4. Install server dependencies on remote ───────────────────────── echo "→ installing server dependencies..." ssh "$HOST" "cd ~/$SERVICE_DIR && cat > package.json << 'PKGJSON' { \"name\": \"celebrate-esc\", \"private\": true, \"workspaces\": [ \"shared\", \"server\" ] } PKGJSON bun install --frozen-lockfile 2>/dev/null || bun install" # ── 5. Create .env on remote if missing ────────────────────────────── echo "→ ensuring .env exists..." ssh "$HOST" "test -f ~/$SERVICE_DIR/.env || cat > ~/$SERVICE_DIR/.env << 'ENVFILE' DATABASE_URL=postgresql://localhost:5433/$DB_NAME PORT=$PORT ENVFILE" # ── 6. Run migrations ──────────────────────────────────────────────── echo "→ pushing database schema..." ssh "$HOST" "cd ~/$SERVICE_DIR/server && DATABASE_URL=postgresql://localhost:5433/$DB_NAME bun drizzle-kit push --force" # ── 7. Deploy static client files ──────────────────────────────────── echo "→ deploying client static files..." ssh "$HOST" "mkdir -p $STATIC_DIR" rsync -az --delete packages/client/dist/ "$HOST:$STATIC_DIR/" # Create .htaccess for SPA routing ssh "$HOST" "cat > $STATIC_DIR/.htaccess << 'HTACCESS' RewriteEngine On RewriteBase /esc/ # Don't rewrite API requests — handled by web backend RewriteCond %{REQUEST_URI} ^/esc/api [NC] RewriteRule . - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.html [L] HTACCESS" # ── 8. Create systemd service ──────────────────────────────────────── echo "→ setting up systemd service..." ssh "$HOST" "cat > ~/.config/systemd/user/esc.service << 'UNIT' [Unit] Description=esc API server After=postgresql.service [Service] Type=simple WorkingDirectory=%h/services/esc/server ExecStart=/usr/bin/bun run --env-file=../.env src/index.ts Restart=on-failure RestartSec=5 [Install] WantedBy=default.target UNIT systemctl --user daemon-reload systemctl --user enable esc.service systemctl --user restart esc.service" # ── 9. Set up web backend routing ──────────────────────────────────── echo "→ configuring web backend routing..." ssh "$HOST" "uberspace web backend add /esc/api PORT $PORT --remove-prefix --force 2>/dev/null || true" # ── 10. Verify ──────────────────────────────────────────────────────── echo "→ verifying deployment..." sleep 2 ssh "$HOST" "systemctl --user status esc.service --no-pager | head -5" echo "" echo "=== deploy complete ===" echo "Frontend: https://serve.uber.space/esc/" echo "API: https://serve.uber.space/esc/api/health"