#!/usr/bin/env bash # Deploy latest code from git and rebuild containers. # Usage: ./deploy.sh (rebuilds site, api, workers) # ./deploy.sh site (rebuilds only site) # ./deploy.sh api (rebuilds only api) # ./deploy.sh erpnext (rebuild + migrate ERPNext, re-extract assets) # ./deploy.sh api workers (rebuild a custom set) set -euo pipefail cd /opt/performancewest SERVICES="${@:-site api workers}" echo "=== Pulling latest from git ===" git pull origin main echo "" echo "=== Building: $SERVICES ===" docker compose build $SERVICES echo "" echo "=== Restarting: $SERVICES ===" docker compose up -d $SERVICES # ── ERPNext: migrate, then ALWAYS re-extract the host asset copy ───────────── # Frappe emits content-hashed asset filenames; an ERPNext rebuild/migrate # changes the hashes. If we don't re-sync the host copy that nginx serves for # portal.performancewest.net, every asset 404s and the portal loses all CSS. # So any time erpnext is (re)built we run bench migrate + re-extract assets. case " $SERVICES " in *" erpnext "*) echo "" echo "=== ERPNext: bench migrate ===" docker compose exec -T erpnext bench --site performancewest.net migrate || \ docker compose exec -T erpnext bench migrate || true echo "" echo "=== ERPNext: re-extracting static assets for the portal ===" sudo ./extract-erpnext-assets.sh ;; esac echo "" echo "=== Clearing nginx cache ===" sudo rm -rf /var/cache/nginx/* 2>/dev/null || true sudo nginx -s reload 2>/dev/null || true # ── Portal asset drift guard ──────────────────────────────────────────────── # Cheap safety net on EVERY deploy: if the portal's manifest references a CSS # bundle that is missing from the host copy, the portal CSS is broken — detect # it and auto-heal by re-extracting. This catches drift from any source # (out-of-band ERPNext restarts, image pulls, etc.). if docker inspect performancewest-erpnext-1 >/dev/null 2>&1; then LOGIN_HASH="$(docker exec performancewest-erpnext-1 sh -c \ "grep -o 'login.bundle.[A-Z0-9]*.css' /home/frappe/frappe-bench/sites/assets/assets.json | head -1" 2>/dev/null || true)" if [ -n "$LOGIN_HASH" ] && \ [ ! -f "/opt/erpnext-assets/assets/frappe/dist/css/${LOGIN_HASH}" ]; then echo "" echo "=== Portal asset drift detected (${LOGIN_HASH} missing) — re-extracting ===" sudo ./extract-erpnext-assets.sh fi fi echo "" echo "=== Done ===" git log --oneline -1 docker compose ps --format "table {{.Name}}\t{{.Status}}" | head -10