#!/usr/bin/env bash # Usage: ./deploy.sh [frontend|backend|all] # default: all # # SSH config (~/.ssh/config) — recommended: # Host innercontext # HostName # User innercontext # # The innercontext user needs passwordless sudo for systemctl only: # /etc/sudoers.d/innercontext-deploy: # innercontext ALL=(root) NOPASSWD: /usr/bin/systemctl restart innercontext, /usr/bin/systemctl restart innercontext-node, /usr/bin/systemctl is-active innercontext, /usr/bin/systemctl is-active innercontext-node set -euo pipefail SERVER="${DEPLOY_SERVER:-innercontext}" # ssh host alias or user@host REMOTE="/opt/innercontext" SCOPE="${1:-all}" # ── Frontend ─────────────────────────────────────────────────────────────── deploy_frontend() { echo "==> [frontend] Building locally..." (cd frontend && pnpm run build) echo "==> [frontend] Uploading build/ and package files..." rsync -az --delete frontend/build/ "$SERVER:$REMOTE/frontend/build/" rsync -az frontend/package.json frontend/pnpm-lock.yaml "$SERVER:$REMOTE/frontend/" echo "==> [frontend] Installing production dependencies on server..." ssh "$SERVER" "cd $REMOTE/frontend && pnpm install --prod --frozen-lockfile" echo "==> [frontend] Restarting service..." ssh "$SERVER" "sudo systemctl restart innercontext-node && echo OK" } # ── Backend ──────────────────────────────────────────────────────────────── deploy_backend() { echo "==> [backend] Uploading source..." rsync -az --delete \ --exclude='.venv/' \ --exclude='__pycache__/' \ --exclude='*.pyc' \ --exclude='.env' \ backend/ "$SERVER:$REMOTE/backend/" echo "==> [backend] Syncing dependencies..." ssh "$SERVER" "cd $REMOTE/backend && uv sync --frozen" echo "==> [backend] Restarting service (alembic runs on start)..." ssh "$SERVER" "sudo systemctl restart innercontext && echo OK" } # ── Dispatch ─────────────────────────────────────────────────────────────── case "$SCOPE" in frontend) deploy_frontend ;; backend) deploy_backend ;; all) deploy_frontend; deploy_backend ;; *) echo "Usage: $0 [frontend|backend|all]" exit 1 ;; esac echo "==> Done."