Traefik defaults to port 80 when no loadbalancer.server.port label exists;
Frappe nginx listens on 8080. expose: 8080 lets the docker provider pick it.
ERPNext gunicorn can exceed 180s + 15 retries (~6.5 min) after migrate.
Use 360s start_period, 20 retries, and fall back to SERVICE_FQDN_FRONTEND
when currentsite.txt is empty. Frontend gets the same Host fallback.
SERVICE_FQDN_FRONTEND_8080 is not generated when the domain is assigned
without a port suffix; Coolify needs SERVICE_URL_FRONTEND_8080 so Traefik
gets loadbalancer.server.port=8080 for Frappe nginx.
Set FRAPPE_SITE_NAME_HEADER from currentsite.txt at frontend start
instead of FRAPPE_SITE_NAME_HEADER=$$host which Coolify writes as an
invalid $host= line in build-time.env.
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.
Filter more bench install noise, set CI=1 to reduce progress spam, and
rely on compose defaults for SITE_NAME/FRAPPE_SITE_NAME_HEADER instead
of literal ${SERVICE_FQDN_FRONTEND} in Coolify env.
First create-site floods Coolify with megabytes of progress output,
which can break the log UI and stall the deploy before backend starts.
Filter those lines in create-site and migrator; redeploy is fast once
the site already exists.
Remove image-preload service (compose creates all containers before it can run); Jenkins and sync-main-from-forgejo.sh load :main on the host internally.
SERVICE_FQDN_FRONTEND from the frontend domain drives site creation and nginx
headers; coolify.env.example adds CUSTOM_IMAGE/CUSTOM_TAG for Jenkins registry pulls.
Co-authored-by: Cursor <cursoragent@cursor.com>
Single compose file for Coolify: MariaDB, Redis, idempotent site creation,
migrations on redeploy, SERVICE_URL_FRONTEND_8080 routing, and Forgejo Actions
readiness validation vendored from production-ci-readiness skill.