gigafibre-fsm/apps/ops/infra/migrate-to-erpnext.sh
louispaulb 13dcd4bf77 feat: add ops app + CONTEXT.md, simplify URL to /ops/
Ops app (Vue/Quasar PWA) with dispatch V2 integration, tag system,
customer 360, tickets, and dashboard. Served via standalone nginx
container at erp.gigafibre.ca/ops/ with Traefik StripPrefix + Authentik SSO.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 22:41:58 -04:00

103 lines
3.8 KiB
Bash
Executable File

#!/bin/bash
# ─────────────────────────────────────────────────────────────────────────────
# migrate-to-erpnext.sh — One-time migration: serve Ops from ERPNext container
#
# Run on the server (96.125.196.67) as root.
# This script:
# 1. Stops and removes the standalone ops-frontend container
# 2. Patches ERPNext docker-compose to add Authentik Traefik labels
# 3. Recreates ERPNext frontend with new labels
#
# After running this, use deploy.sh to push new builds.
# ─────────────────────────────────────────────────────────────────────────────
set -e
# Find ERPNext compose file
ERP_COMPOSE=""
for p in /opt/erpnext/docker-compose.yml /opt/frappe_docker/docker-compose.yml; do
[ -f "$p" ] && ERP_COMPOSE="$p" && break
done
[ -z "$ERP_COMPOSE" ] && echo "ERROR: ERPNext docker-compose not found" && exit 1
ERP_DIR="$(dirname "$ERP_COMPOSE")"
echo "=== Targo Ops Infrastructure Simplification ==="
echo "Using: $ERP_COMPOSE"
echo ""
# ── Step 1: Stop ops-frontend container ──
echo "==> Step 1: Stopping ops-frontend container..."
if docker ps -a --format '{{.Names}}' | grep -q 'ops-frontend'; then
(cd /opt/ops-app/infra 2>/dev/null && docker compose down 2>/dev/null) || \
(docker stop ops-frontend 2>/dev/null; docker rm ops-frontend 2>/dev/null) || true
echo " Done."
else
echo " Already removed."
fi
# ── Step 2: Patch docker-compose.yml ──
echo ""
echo "==> Step 2: Adding Authentik labels to ERPNext frontend..."
if grep -q 'routers.ops-app' "$ERP_COMPOSE"; then
echo " Already present. Skipping."
else
cp "$ERP_COMPOSE" "${ERP_COMPOSE}.bak"
python3 <<PYEOF
import re
compose_path = "$ERP_COMPOSE"
with open(compose_path) as f:
content = f.read()
# Labels to inject
ops_labels = ''' # ── Ops SPA (Authentik-protected) ──
- "traefik.http.routers.ops-app.rule=Host(\`erp.gigafibre.ca\`) && PathPrefix(\`/assets/ops-app\`)"
- "traefik.http.routers.ops-app.entrypoints=web,websecure"
- "traefik.http.routers.ops-app.middlewares=authentik@file"
- "traefik.http.routers.ops-app.service=erp"
- "traefik.http.routers.ops-app.tls.certresolver=letsencrypt"
- "traefik.http.routers.ops-app.priority=200"
# ── Authentik outpost callback ──
- "traefik.http.routers.ops-ak.rule=Host(\`erp.gigafibre.ca\`) && PathPrefix(\`/outpost.goauthentik.io/\`)"
- "traefik.http.routers.ops-ak.entrypoints=web,websecure"
- "traefik.http.routers.ops-ak.middlewares=authentik@file"
- "traefik.http.routers.ops-ak.service=erp"
- "traefik.http.routers.ops-ak.tls.certresolver=letsencrypt"
- "traefik.http.routers.ops-ak.priority=250"'''
# Find the last traefik label line and insert after it
lines = content.split('\\n')
last_traefik_idx = -1
for i, line in enumerate(lines):
if 'traefik.' in line and line.strip().startswith('-'):
last_traefik_idx = i
if last_traefik_idx == -1:
print("ERROR: No traefik labels found in compose file")
exit(1)
lines.insert(last_traefik_idx + 1, ops_labels)
with open(compose_path, 'w') as f:
f.write('\\n'.join(lines))
print(f" Injected after line {last_traefik_idx + 1}. Backup: {compose_path}.bak")
PYEOF
fi
# ── Step 3: Recreate ERPNext frontend ──
echo ""
echo "==> Step 3: Recreating ERPNext frontend..."
cd "$ERP_DIR"
docker compose up -d frontend
echo " Done."
echo ""
echo "=== Migration complete ==="
echo ""
echo "Deploy ops build: ./deploy.sh"
echo "Access: https://erp.gigafibre.ca/assets/ops-app/"
echo "Cleanup: rm -rf /opt/ops-app"
echo ""