Fix backend healthcheck for multi-site Frappe routing

Frappe returns 404 on /api/method/ping without a Host header matching
the site name. Pass SERVICE_FQDN_FRONTEND in healthchecks and drop
SITE_NAME env indirection that Coolify was caching as a literal.
This commit is contained in:
epistemophiliac 2026-06-16 22:10:38 -04:00
parent cfee4fcfa3
commit 416b0f8109
2 changed files with 12 additions and 10 deletions

View file

@ -104,14 +104,14 @@ services:
- > - >
export CI=1; export CI=1;
B=/usr/local/bin/bench; B=/usr/local/bin/bench;
SITE=$$SITE_NAME; SITE=$$SERVICE_FQDN_FRONTEND;
if [ -z "$$SITE" ]; then echo "[create-site] ERROR: SITE_NAME empty — assign domain to frontend:8080 in Coolify (SERVICE_FQDN_FRONTEND)"; exit 1; fi; if [ -z "$$SITE" ]; then echo "[create-site] ERROR: SERVICE_FQDN_FRONTEND empty — assign domain to frontend:8080 in Coolify"; exit 1; fi;
wait-for-it -t 120 db:3306; wait-for-it -t 120 db:3306;
wait-for-it -t 120 redis-cache:6379; wait-for-it -t 120 redis-cache:6379;
wait-for-it -t 120 redis-queue:6379; wait-for-it -t 120 redis-queue:6379;
if [ -d "sites/$$SITE" ]; then echo "[create-site] exists"; $$B use "$$SITE"; else echo "[create-site] creating (10-20 min first time — verbose progress suppressed)"; INSTALL_ARGS=""; IFS=',' read -r -a apps <<< "$$INSTALL_APPS"; for app in "$${apps[@]}"; do INSTALL_ARGS="$$INSTALL_ARGS --install-app $$app"; done; set -o pipefail; $$B new-site "$$SITE" --mariadb-user-host-login-scope='%' --admin-password "$$ADMIN_PASSWORD" --db-root-password "$$DB_PASSWORD" $$INSTALL_ARGS --set-default 2>&1 | grep -vE '^Updating DocTypes for |^Creating Workspace|^Creating Desktop Icons|^Updating Dashboard for |^\* Installing |^Patching Existing|^rename_field:|^Thank you for installing|^Setting up Frappe HR'; fi if [ -d "sites/$$SITE" ]; then echo "[create-site] exists"; $$B use "$$SITE"; else echo "[create-site] creating (10-20 min first time — verbose progress suppressed)"; INSTALL_ARGS=""; IFS=',' read -r -a apps <<< "$$INSTALL_APPS"; for app in "$${apps[@]}"; do INSTALL_ARGS="$$INSTALL_ARGS --install-app $$app"; done; set -o pipefail; $$B new-site "$$SITE" --mariadb-user-host-login-scope='%' --admin-password "$$ADMIN_PASSWORD" --db-root-password "$$DB_PASSWORD" $$INSTALL_ARGS --set-default 2>&1 | grep -vE '^Updating DocTypes for |^Creating Workspace|^Creating Desktop Icons|^Updating Dashboard for |^\* Installing |^Patching Existing|^rename_field:|^Thank you for installing|^Setting up Frappe HR'; fi
environment: environment:
- 'SITE_NAME=${SITE_NAME:-${SERVICE_FQDN_FRONTEND}}' - SERVICE_FQDN_FRONTEND
- 'ADMIN_PASSWORD=${ADMIN_PASSWORD:-changeme}' - 'ADMIN_PASSWORD=${ADMIN_PASSWORD:-changeme}'
- 'DB_PASSWORD=${DB_PASSWORD:-changeme}' - 'DB_PASSWORD=${DB_PASSWORD:-changeme}'
- 'INSTALL_APPS=${INSTALL_APPS:-erpnext,payments,hrms,lending,lms}' - 'INSTALL_APPS=${INSTALL_APPS:-erpnext,payments,hrms,lending,lms}'
@ -144,6 +144,7 @@ services:
backend: backend:
<<: *backend_defaults <<: *backend_defaults
environment: environment:
- SERVICE_FQDN_FRONTEND
- 'GUNICORN_THREADS=${GUNICORN_THREADS:-4}' - 'GUNICORN_THREADS=${GUNICORN_THREADS:-4}'
- 'GUNICORN_WORKERS=${GUNICORN_WORKERS:-2}' - 'GUNICORN_WORKERS=${GUNICORN_WORKERS:-2}'
- 'GUNICORN_TIMEOUT=${GUNICORN_TIMEOUT:-120}' - 'GUNICORN_TIMEOUT=${GUNICORN_TIMEOUT:-120}'
@ -155,11 +156,11 @@ services:
migrator: migrator:
condition: service_completed_successfully condition: service_completed_successfully
healthcheck: healthcheck:
test: ['CMD-SHELL', 'curl -sf http://localhost:8000/api/method/ping || exit 1'] test: ['CMD-SHELL', 'curl -sf -H "Host: $$SERVICE_FQDN_FRONTEND" http://127.0.0.1:8000/api/method/ping || exit 1']
interval: 15s interval: 15s
timeout: 10s timeout: 10s
retries: 10 retries: 15
start_period: 120s start_period: 180s
websocket: websocket:
<<: [*depends_on_configurator, *customizable_image, *frappe_platform, *sites_volume] <<: [*depends_on_configurator, *customizable_image, *frappe_platform, *sites_volume]
@ -180,7 +181,7 @@ services:
- SERVICE_FQDN_FRONTEND - SERVICE_FQDN_FRONTEND
- 'BACKEND=backend:8000' - 'BACKEND=backend:8000'
- 'SOCKETIO=websocket:9000' - 'SOCKETIO=websocket:9000'
- 'FRAPPE_SITE_NAME_HEADER=${FRAPPE_SITE_NAME_HEADER:-${SERVICE_FQDN_FRONTEND}}' - 'FRAPPE_SITE_NAME_HEADER=${SERVICE_FQDN_FRONTEND}'
- 'UPSTREAM_REAL_IP_ADDRESS=${UPSTREAM_REAL_IP_ADDRESS:-127.0.0.1}' - 'UPSTREAM_REAL_IP_ADDRESS=${UPSTREAM_REAL_IP_ADDRESS:-127.0.0.1}'
- 'UPSTREAM_REAL_IP_HEADER=${UPSTREAM_REAL_IP_HEADER:-X-Forwarded-For}' - 'UPSTREAM_REAL_IP_HEADER=${UPSTREAM_REAL_IP_HEADER:-X-Forwarded-For}'
- 'UPSTREAM_REAL_IP_RECURSIVE=${UPSTREAM_REAL_IP_RECURSIVE:-off}' - 'UPSTREAM_REAL_IP_RECURSIVE=${UPSTREAM_REAL_IP_RECURSIVE:-off}'
@ -194,11 +195,11 @@ services:
websocket: websocket:
condition: service_started condition: service_started
healthcheck: healthcheck:
test: ['CMD-SHELL', 'curl -sf http://localhost:8080/ || exit 1'] test: ['CMD-SHELL', 'curl -sf -H "Host: $$SERVICE_FQDN_FRONTEND" http://127.0.0.1:8080/api/method/ping || exit 1']
interval: 15s interval: 15s
timeout: 10s timeout: 10s
retries: 15 retries: 15
start_period: 90s start_period: 120s
queue-short: queue-short:
<<: *backend_defaults <<: *backend_defaults

View file

@ -80,7 +80,8 @@ Login: `https://your-domain` — user `Administrator`, password = `ADMIN_PASSWOR
| Symptom | Fix | | Symptom | Fix |
|---------|-----| |---------|-----|
| `SITE_NAME empty` on create-site | Assign domain on `frontend:8080` before deploy | | Backend unhealthy / deploy fails after migrator | Healthcheck must send `Host: <site>` — fixed in compose; redeploy |
| `SITE_NAME empty` on create-site | Assign domain on `frontend:8080` before deploy (`SERVICE_FQDN_FRONTEND`) |
| Wrong site / 404 nginx | Delete old `SITE_NAME` in Coolify UI; ensure header matches domain | | Wrong site / 404 nginx | Delete old `SITE_NAME` in Coolify UI; ensure header matches domain |
| Site created with wrong name | Wipe `sites` volume or rename site manually — env change alone won't rename | | Site created with wrong name | Wipe `sites` volume or rename site manually — env change alone won't rename |
| Deploy log page crashes / blank | First `create-site` is huge — fixed by filtering DocType spam; redeploy after site exists | | Deploy log page crashes / blank | First `create-site` is huge — fixed by filtering DocType spam; redeploy after site exists |