- apps/ops/infra/nginx.conf brought back in sync with the live working conf (was missing the /hub proxy + /auth/whoami → deploying the old template would have broken OPS). Tokens are placeholders (__ERP_API_TOKEN__ / __HUB_TOKEN__), never real values. - deploy.sh now renders nginx.conf on every deploy: substitutes the tokens from the server's /opt/targo-hub/.env (ERP_TOKEN = service account, not Administrator; HUB_SERVICE_TOKEN), validates via throwaway nginx -t, then restarts ops-frontend. Fixes the "nginx.conf deleted from host → OPS down on restart" landmine and makes token rotation a one-command redeploy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
91 lines
4.0 KiB
Bash
Executable File
91 lines
4.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# deploy.sh — Build Targo Ops PWA and deploy to ops-frontend nginx container
|
|
#
|
|
# The ops app is served by a standalone nginx container (ops-frontend) at
|
|
# erp.gigafibre.ca/ops/. Traefik strips /ops prefix before proxying to nginx.
|
|
# Authentik protection is handled via Traefik forwardAuth middleware.
|
|
#
|
|
# Static files go to /opt/ops-app/ on the host, mounted into the container.
|
|
#
|
|
# Usage:
|
|
# ./deploy.sh # deploy to remote server (SPA mode, no service worker cache)
|
|
# ./deploy.sh local # deploy to local Docker (development)
|
|
# ./deploy.sh pwa # deploy to remote server (PWA mode, for production)
|
|
#
|
|
# Prerequisites (remote):
|
|
# - SSH key ~/.ssh/proxmox_vm for root@96.125.196.67
|
|
# - ops-frontend container running (see infra/docker-compose.yaml)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
SERVER="root@96.125.196.67"
|
|
SSH_KEY="$HOME/.ssh/proxmox_vm"
|
|
DEST="/opt/ops-app"
|
|
|
|
# Default to SPA mode (no service worker = no cache headaches during dev)
|
|
BUILD_MODE="spa"
|
|
DIST_DIR="dist/spa"
|
|
if [ "$1" = "pwa" ]; then
|
|
BUILD_MODE="pwa"
|
|
DIST_DIR="dist/pwa"
|
|
shift
|
|
fi
|
|
|
|
echo "==> Installing dependencies..."
|
|
npm ci --silent
|
|
|
|
echo "==> Building $BUILD_MODE (base=/ops/)..."
|
|
DEPLOY_BASE=/ops/ npx quasar build -m "$BUILD_MODE"
|
|
|
|
if [ "$1" = "local" ]; then
|
|
# ── Local deploy ──
|
|
echo "==> Deploying to local $DEST..."
|
|
rm -rf "$DEST"/*
|
|
cp -r "$DIST_DIR"/* "$DEST/"
|
|
echo ""
|
|
echo "Done! Targo Ops: http://localhost/ops/"
|
|
else
|
|
# ── Remote deploy ──
|
|
echo "==> Packaging..."
|
|
tar czf /tmp/ops-build.tar.gz -C "$DIST_DIR" .
|
|
|
|
echo "==> Deploying to $SERVER..."
|
|
cat /tmp/ops-build.tar.gz | ssh -i "$SSH_KEY" "$SERVER" \
|
|
"cat > /tmp/ops.tar.gz && \
|
|
rm -rf $DEST/*.js $DEST/*.html $DEST/*.json $DEST/assets $DEST/icons $DEST/sw.js $DEST/workbox-*.js && \
|
|
cd $DEST && tar xzf /tmp/ops.tar.gz && \
|
|
rm -f /tmp/ops.tar.gz"
|
|
|
|
rm -f /tmp/ops-build.tar.gz
|
|
|
|
# ── Render nginx.conf from the versioned template, injecting tokens SERVER-SIDE ──
|
|
# Tokens live only on the server (/opt/targo-hub/.env): ERP_TOKEN = ERPNext service account
|
|
# (hub-service@targo.ca, NOT Administrator) · HUB_SERVICE_TOKEN = hub Bearer. They are never
|
|
# in the repo, never in the JS bundle. This makes the conf reproducible (fixes the past
|
|
# "nginx.conf deleted from host → ops down on restart" landmine) and rotation a one-command redeploy.
|
|
echo "==> Rendering nginx.conf (server-side token injection)..."
|
|
scp -i "$SSH_KEY" infra/nginx.conf "$SERVER":/tmp/ops-nginx.tmpl
|
|
ssh -i "$SSH_KEY" "$SERVER" '
|
|
set -e
|
|
ERP=$(grep -E "^ERP_TOKEN=" /opt/targo-hub/.env | cut -d= -f2-)
|
|
HUB=$(grep -E "^HUB_SERVICE_TOKEN=" /opt/targo-hub/.env | cut -d= -f2-)
|
|
[ -z "$HUB" ] && HUB=$(grep -E "^HUB_TOKEN=" /opt/targo-hub/.env | cut -d= -f2-)
|
|
if [ -z "$ERP" ] || [ -z "$HUB" ]; then echo "ABORT: ERP_TOKEN/HUB token missing in /opt/targo-hub/.env"; exit 1; fi
|
|
sed -e "s#__ERP_API_TOKEN__#${ERP}#g" -e "s#__HUB_TOKEN__#${HUB}#g" /tmp/ops-nginx.tmpl > '"$DEST"'/nginx.conf
|
|
rm -f /tmp/ops-nginx.tmpl
|
|
# validate against a throwaway nginx before touching the live container
|
|
docker run --rm -v '"$DEST"'/nginx.conf:/etc/nginx/conf.d/default.conf:ro nginx:alpine nginx -t
|
|
# restart re-binds the file (avoids stale //deleted inode); ~1s blip
|
|
docker restart ops-frontend >/dev/null
|
|
sleep 2
|
|
docker exec ops-frontend sh -c "wget -qO- http://127.0.0.1/api/method/frappe.auth.get_logged_user 2>/dev/null" | head -c 80; echo
|
|
'
|
|
|
|
echo ""
|
|
echo "Done! Targo Ops ($BUILD_MODE): https://erp.gigafibre.ca/ops/"
|
|
fi
|