From 6731a8d62ef7e508919c626dce6eee3dfee696dc Mon Sep 17 00:00:00 2001 From: aarroyo Date: Fri, 21 Aug 2026 21:44:16 -0500 Subject: [PATCH] fix(infra): two of the three UAT domain variables named a service that does not exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Symptom: after a successful Coolify deploy with all nine containers healthy, every domain answered 503 and the containers carried zero Traefik labels. Cause, read out of Coolify's own source on the host rather than guessed. `normalizeComposeServiceName` (bootstrap/helpers/domains.php:335) derives the magic-variable key from the compose SERVICE NAME with `-` and `.` replaced by `_`. So `core-api` yields `CORE_API` and `tracker-web` yields `TRACKER_WEB`. This file declared `SERVICE_FQDN_COREAPI_3000` and `SERVICE_FQDN_TRACKERWEB_8080` — names matching no service. The failure is silent in the direction that costs time. Coolify still creates the environment variable, so it LOOKS declared; what it does not create is the domain entry in `docker_compose_domains`, and the domain field never appears in the UI. Confirmed on the live install: `docker_compose_domains` held exactly one key, `mcp` — the only one of the three whose name has no hyphen and therefore normalises to itself. The two mistyped services had no route at all, and the variables Coolify generates are read-only in the UI (they are derived on every parse), so there was nothing to correct by hand either. Co-Authored-By: Claude Opus 5 --- product/infra/docker-compose.uat.yml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/product/infra/docker-compose.uat.yml b/product/infra/docker-compose.uat.yml index b551e96f..72f7d7ba 100644 --- a/product/infra/docker-compose.uat.yml +++ b/product/infra/docker-compose.uat.yml @@ -71,9 +71,16 @@ services: CORE_PATH: /app/corpus WORKSPACE_ROOT: /app/corpus REDIS_URL: redis://redis:6379 - # Coolify magic variable: declaring it assigns this service a domain and - # routes it to port 3000. The value is filled in by Coolify at deploy time. - SERVICE_FQDN_COREAPI_3000: "" + # Coolify magic variable: declaring it gives this service a domain field and + # routes that domain to port 3000. + # + # The name is NOT free-form. `normalizeComposeServiceName` (Coolify's + # domains.php) derives the key from the compose service name with `-` + # replaced by `_`, so `core-api` yields CORE_API. `COREAPI` was here first + # and matched nothing: Coolify created the variable but never a domain + # field, so the service had no route and the proxy answered 503. `mcp` + # worked by luck — a name with no hyphen normalises to itself. + SERVICE_FQDN_CORE_API_3000: "" expose: ["3000"] depends_on: redis: @@ -249,8 +256,9 @@ services: # (`evolith-tracker-api:80`), which does not resolve on this network. # nginx proxies /api/ here, which is also what keeps the SPA same-origin. TRACKER_API_UPSTREAM: http://tracker-api:8080 - # The surface a UAT client actually opens in a browser. - SERVICE_FQDN_TRACKERWEB_8080: "" + # The surface a UAT client actually opens in a browser. TRACKER_WEB, not + # TRACKERWEB — see the note on core-api above. + SERVICE_FQDN_TRACKER_WEB_8080: "" expose: ["8080"] depends_on: tracker-api: