From b8be95c283dc7ca1d5d9256f3a47fc1e73adcdb1 Mon Sep 17 00:00:00 2001 From: Jeremi Joslin Date: Thu, 20 Aug 2026 15:47:17 +0200 Subject: [PATCH] fix(hosted): give routed eSignet proxies Coolify-resolvable names Coolify validates a routed service against the compose key but resolves it after rewriting "-" to "_", so a hyphenated name is stored where the router never reads it and the domain can only be set from the UI. Name the two routed proxies with underscores so the issuer edge is manageable. Signed-off-by: Jeremi Joslin --- compose.coolify.esignet.yaml | 6 ++++-- scripts/test_hosted_esignet_topology.py | 6 +++--- scripts/test_runtime_topology.py | 22 +++++++++++++++++----- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/compose.coolify.esignet.yaml b/compose.coolify.esignet.yaml index e4b0c52..d2eb6ec 100644 --- a/compose.coolify.esignet.yaml +++ b/compose.coolify.esignet.yaml @@ -87,7 +87,7 @@ services: labels: solmara.rollout.slot: authority-cells - esignet-ui: + esignet_ui: image: ${SOLMARA_ESIGNET_UI_IMAGE:?set digest-pinned eSignet UI image} environment: SOLMARA_ESIGNET_PUBLIC_HOST: ${SOLMARA_ESIGNET_PUBLIC_HOST:-esignet.solmara.registrystack.org} @@ -102,7 +102,9 @@ services: # neither its OpenID discovery document nor its RFC 8414 authorization-server # metadata. The UI image is a host-agnostic reverse proxy that serves both at # the root and forwards /v1/esignet, so it also fronts the issuer origin. - esignet-edge: + # Coolify matches a routed service against the compose key but resolves it + # after rewriting "-" to "_", so both proxies carry underscore names. + esignet_edge: image: ${SOLMARA_ESIGNET_UI_IMAGE:?set digest-pinned eSignet UI image} environment: SOLMARA_ESIGNET_PUBLIC_HOST: ${SOLMARA_ESIGNET_PUBLIC_HOST:-esignet.solmara.registrystack.org} diff --git a/scripts/test_hosted_esignet_topology.py b/scripts/test_hosted_esignet_topology.py index d70fc87..4a7e1d1 100644 --- a/scripts/test_hosted_esignet_topology.py +++ b/scripts/test_hosted_esignet_topology.py @@ -46,15 +46,15 @@ def test_compose_is_a_standalone_esignet_app(self) -> None: "esignet-database", "esignet-redis", "esignet", - "esignet-ui", - "esignet-edge", + "esignet_ui", + "esignet_edge", "esignet-seed", }, ) # The issuer origin is fronted by the proxy image, not by eSignet # itself, so its discovery documents are reachable where the issuer # says they are. - self.assertEqual(services["esignet-edge"]["image"], services["esignet-ui"]["image"]) + self.assertEqual(services["esignet_edge"]["image"], services["esignet_ui"]["image"]) self.assertNotIn("solmara.lab.host", services["esignet"]["labels"]) self.assertNotIn("portal", services) self.assertEqual( diff --git a/scripts/test_runtime_topology.py b/scripts/test_runtime_topology.py index 8a2b692..791a3dd 100644 --- a/scripts/test_runtime_topology.py +++ b/scripts/test_runtime_topology.py @@ -751,8 +751,8 @@ def test_hosted_esignet_is_standalone_and_core_portal_owns_login_config( "esignet-database", "esignet-redis", "esignet", - "esignet-ui", - "esignet-edge", + "esignet_ui", + "esignet_edge", "esignet-seed", }, ) @@ -813,16 +813,28 @@ def test_hosted_esignet_publishes_discovery_at_its_issuer_root(self) -> None: straight at it leaves `{issuer}/.well-known/openid-configuration` and the RFC 8414 authorization-server document unserved. The UI image is a host-agnostic reverse proxy that publishes both, so the public host - belongs to an edge instance of it and the service stays unrouted.""" + belongs to an edge instance of it and the service stays unrouted. + + Both proxies carry underscore names because Coolify accepts a routed + service only under its compose key but resolves it after rewriting "-" + to "_", so a hyphenated name is stored where routing never reads.""" esignet_path = SCRIPT.parents[1] / "compose.coolify.esignet.yaml" services = yaml.safe_load(esignet_path.read_text(encoding="utf-8"))["services"] - edge = services["esignet-edge"] - self.assertEqual(edge["image"], services["esignet-ui"]["image"]) + edge = services["esignet_edge"] + self.assertEqual(edge["image"], services["esignet_ui"]["image"]) self.assertEqual( edge["labels"]["solmara.lab.host"], "${SOLMARA_ESIGNET_PUBLIC_HOST:-esignet.solmara.registrystack.org}", ) self.assertNotIn("solmara.lab.host", services["esignet"].get("labels") or {}) + routed = [ + name + for name, service in services.items() + if "solmara.lab.host" in (service.get("labels") or {}) + ] + self.assertEqual(sorted(routed), ["esignet_edge", "esignet_ui"]) + for name in routed: + self.assertNotIn("-", name) def test_bruno_workspace_covers_only_the_eight_governed_v2_lookups(self) -> None: relay_requests = SCRIPT.parents[1] / "requests/registry-lab/50 - Relay V2"