Two bugs in the generated nginx vhosts surface when adding an extra domain to a deployment on a shared host. Both live in internal/nginx/manager.go / templates/infra/nginx/nginx.conf.
1. Additional-domain upstream uses the bare service name (routes to the wrong deployment)
The multi/additional-domain templates emit:
set $upstream {{.Service}}:{{.ContainerPort}};
proxy_pass {{.Protocol}}://$upstream;
resolver 127.0.0.11 valid=30s ipv6=off;
.Service is the Compose service name (commonly app), which is not unique across deployments. The shared proxy is attached to multiple project networks, so a service name like app resolves via the embedded DNS (127.0.0.11) to an arbitrary deployment's container. A custom domain then intermittently serves a different deployment on the box (whichever app the resolver returns), per request.
Reproduced: on a host running several stacks that each define a service named app, repeated requests to one deployment's domain return responses from different containers (for example different runtime versions in the response headers), confirming non-deterministic cross-deployment routing.
The primary-domain templates correctly use {{.DeploymentName}}:80 (unique). Only the multi/additional-domain path uses {{.Service}}.
Impact: cross-tenant request routing, non-deterministic, easy to miss because it sometimes hits the right container.
Proposed fix (configurable)
- Resolve the additional-domain upstream to a deployment-scoped target. The agent already assigns a unique
container_name per service (EnsureContainerNames); use that (or a per-deployment network alias) instead of the bare service name.
- Surface the upstream target per domain in the UI/API. The Add Domain form lists only the service key (so duplicate keys like
app across projects are indistinguishable) and Container Port, with no way to point at the unique container, so there is no workaround short of renaming service keys.
2. server_names_hash_bucket_size is a fixed value and not synced to existing installs
Adding a long hostname fails nginx -t with:
could not build server_names_hash, you should increase server_names_hash_bucket_size: 64
so the save rolls back. The base template (templates/infra/nginx/nginx.conf:24) sets 128, but:
- existing installs still run the old value (the base http config is not re-applied on upgrade or on domain changes), and
128 is a fixed ceiling that more or longer domains can still exceed.
Proposed fix (configurable)
- Make
server_names_hash_bucket_size (and server_names_hash_max_size) configurable, with a safe default, and/or auto-size from the count and longest length of configured domains.
- Re-apply the base http config on agent upgrade and when adding domains.
Acceptance
- Adding a second domain to a deployment routes only to that deployment's container, verified on a host running multiple stacks that share a service name.
- Adding many long domains passes
nginx -t and reloads on a freshly upgraded existing install, with no manual edits.
Files: internal/nginx/manager.go (multi-domain templates), templates/infra/nginx/nginx.conf.
Two bugs in the generated nginx vhosts surface when adding an extra domain to a deployment on a shared host. Both live in
internal/nginx/manager.go/templates/infra/nginx/nginx.conf.1. Additional-domain upstream uses the bare service name (routes to the wrong deployment)
The multi/additional-domain templates emit:
.Serviceis the Compose service name (commonlyapp), which is not unique across deployments. The shared proxy is attached to multiple project networks, so a service name likeappresolves via the embedded DNS (127.0.0.11) to an arbitrary deployment's container. A custom domain then intermittently serves a different deployment on the box (whicheverappthe resolver returns), per request.Reproduced: on a host running several stacks that each define a service named
app, repeated requests to one deployment's domain return responses from different containers (for example different runtime versions in the response headers), confirming non-deterministic cross-deployment routing.The primary-domain templates correctly use
{{.DeploymentName}}:80(unique). Only the multi/additional-domain path uses{{.Service}}.Impact: cross-tenant request routing, non-deterministic, easy to miss because it sometimes hits the right container.
Proposed fix (configurable)
container_nameper service (EnsureContainerNames); use that (or a per-deployment network alias) instead of the bare service name.appacross projects are indistinguishable) and Container Port, with no way to point at the unique container, so there is no workaround short of renaming service keys.2.
server_names_hash_bucket_sizeis a fixed value and not synced to existing installsAdding a long hostname fails
nginx -twith:so the save rolls back. The base template (
templates/infra/nginx/nginx.conf:24) sets128, but:128is a fixed ceiling that more or longer domains can still exceed.Proposed fix (configurable)
server_names_hash_bucket_size(andserver_names_hash_max_size) configurable, with a safe default, and/or auto-size from the count and longest length of configured domains.Acceptance
nginx -tand reloads on a freshly upgraded existing install, with no manual edits.Files:
internal/nginx/manager.go(multi-domain templates),templates/infra/nginx/nginx.conf.