TGICS/deploy.sh

142 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Deploy TGICS (frontend + API) to the VirtualEngage EC2 host.
#
# Usage:
# ./deploy.sh
#
# Env overrides:
# DEPLOY_KEY default ~/Documents/Keys/VirtualEngage.pem
# DEPLOY_HOST default ubuntu@15.207.15.52
# DEPLOY_PATH default /var/www/tgics
# DEPLOY_SITE default https://tgics.cttr.in
# API_PORT default 3050
set -euo pipefail
ROOT="$(cd "$(dirname "$0")" && pwd)"
SSH_KEY="${DEPLOY_KEY:-$HOME/Documents/Keys/VirtualEngage.pem}"
SSH_HOST="${DEPLOY_HOST:-ubuntu@15.207.15.52}"
REMOTE_DIR="${DEPLOY_PATH:-/var/www/tgics}"
SITE="${DEPLOY_SITE:-https://tgics.cttr.in}"
API_PORT="${API_PORT:-3050}"
PM2_NAME="tgics-api"
SSH_OPTS=(-i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new)
ssh_cmd() {
ssh "${SSH_OPTS[@]}" "$SSH_HOST" "$@"
}
rsync_cmd() {
rsync -az --delete --progress \
-e "ssh ${SSH_OPTS[*]}" \
"$@"
}
if [[ ! -f "$SSH_KEY" ]]; then
echo "SSH key not found: $SSH_KEY" >&2
exit 1
fi
chmod 400 "$SSH_KEY" 2>/dev/null || true
echo "==> Building frontend (same-origin API via nginx)"
(
cd "$ROOT/frontend"
npm ci --cache "$ROOT/.npm-cache"
# Empty base → browser calls /api on tgics.cttr.in (proxied to Hapi)
VITE_API_BASE= npx vite build
)
echo "==> Ensuring remote directories"
ssh_cmd "sudo mkdir -p '$REMOTE_DIR/frontend/dist' '$REMOTE_DIR/backend' '$REMOTE_DIR/deploy' && sudo chown -R ubuntu:ubuntu '$REMOTE_DIR'"
echo "==> Syncing frontend build"
rsync_cmd \
"$ROOT/frontend/dist/" \
"$SSH_HOST:$REMOTE_DIR/frontend/dist/"
echo "==> Syncing backend (keeps remote .env)"
rsync_cmd \
--exclude node_modules \
--exclude .env \
"$ROOT/backend/" \
"$SSH_HOST:$REMOTE_DIR/backend/"
echo "==> Syncing deploy assets"
rsync_cmd \
"$ROOT/deploy/" \
"$SSH_HOST:$REMOTE_DIR/deploy/"
echo "==> Installing deps, configuring nginx, restarting PM2"
ssh_cmd \
"REMOTE_DIR=$(printf '%q' "$REMOTE_DIR") SITE=$(printf '%q' "$SITE") API_PORT=$(printf '%q' "$API_PORT") PM2_NAME=$(printf '%q' "$PM2_NAME") bash -s" <<'REMOTE'
set -euo pipefail
export PATH="/usr/bin:/usr/local/bin:$PATH"
cd "$REMOTE_DIR/backend"
if [[ ! -f .env ]]; then
if [[ ! -f .env.example ]]; then
echo "Missing $REMOTE_DIR/backend/.env on the server." >&2
exit 1
fi
cp .env.example .env
python3 - <<PY
from pathlib import Path
import re
path = Path(".env")
text = path.read_text()
site = ${SITE@Q}
port = ${API_PORT@Q}
def upsert(text, key, value):
line = f"{key}={value}"
pattern = re.compile("^" + re.escape(key) + r"=.*$", re.M)
if pattern.search(text):
return pattern.sub(line, text, count=1)
return text.rstrip() + "\n" + line + "\n"
text = upsert(text, "HOST", "127.0.0.1")
text = upsert(text, "PORT", str(port))
text = upsert(text, "FRONTEND_ORIGIN", site)
path.write_text(text)
print("Seeded backend/.env from example — edit DB_* / RAPPORT_ACCESS_TOKEN / JWT_SECRET")
PY
else
echo "Keeping existing backend/.env"
fi
if ! command -v pm2 >/dev/null 2>&1; then
sudo npm install -g pm2
fi
npm ci --omit=dev
pm2 startOrReload ecosystem.config.cjs --update-env
pm2 save
pm2 status "$PM2_NAME"
NGINX_AVAIL="/etc/nginx/sites-available/tgics"
NGINX_ENABLED="/etc/nginx/sites-enabled/tgics"
if [[ -f "$REMOTE_DIR/deploy/nginx-tgics.conf" ]]; then
sudo cp "$REMOTE_DIR/deploy/nginx-tgics.conf" "$NGINX_AVAIL"
sudo ln -sfn "$NGINX_AVAIL" "$NGINX_ENABLED"
sudo nginx -t
sudo systemctl reload nginx
echo "Nginx site installed for tgics.cttr.in"
fi
sleep 1
curl -fsS "http://127.0.0.1:${API_PORT}/health"
echo
REMOTE
echo "==> Deployed to $SSH_HOST:$REMOTE_DIR"
echo " Site: $SITE"
echo " API: pm2 $PM2_NAME → 127.0.0.1:$API_PORT"
echo " First time:"
echo " 1) Point DNS tgics.cttr.in → 15.207.15.52"
echo " 2) Edit $REMOTE_DIR/backend/.env (DB_*, RAPPORT_ACCESS_TOKEN, JWT_SECRET)"
echo " 3) ssh … 'cd $REMOTE_DIR/backend && pm2 restart $PM2_NAME --update-env'"
echo " 4) sudo certbot --nginx -d tgics.cttr.in"