Description and Error Message
On a Docker Compose service whose domain includes a port (e.g. https://app.example.com:3000, as produced by SERVICE_FQDN_WEB_3000), setting Search engine indexing → Noindex has no effect: after a deploy the generated Traefik labels contain no X-Robots-Tag middleware, and responses carry no X-Robots-Tag header. No error is logged.
This worked on v4.3.10 and stopped working after upgrading to v4.3.23. The two sides of the noindex comparison normalize domains differently:
HasNoindexDomains::noindexDomains() strips the port via normalizeNoindexDomain() → DomainPortOverrides::withoutPort() (HasNoindexDomains.php#L74-L76). This was added in v4.3.15. The stored flag becomes https://app.example.com.
isNoindexDomain() normalizes only with ValidationPatterns::normalizeApplicationDomainUrl(), which keeps the port (docker.php#L537-L546).
fqdnLabelsForTraefik() calls isNoindexDomain($domain, …) with the raw domain, port included (docker.php#L759; same for Caddy at L585). For service applications $domain comes from ServiceApplication::fqdns(), a plain explode(',', $this->fqdn).
So https://app.example.com:3000 is compared against https://app.example.com, never matches, and the middleware is never emitted.
Re-saving the domain in the UI does not help: the save still stores fqdn with the embedded port (https://app.example.com:3000) while noindex_domains is stored portless.
Expected Behavior
- A domain marked Noindex gets the
X-Robots-Tag: noindex, nofollow middleware regardless of whether its stored FQDN includes a port.
- Both sides of the comparison use the same normalization. Likely fix: in
isNoindexDomain(), wrap both normalizations in DomainPortOverrides::withoutPort() (or reuse the trait's normalizeNoindexDomain() logic).
Steps to Reproduce
- Create a Docker Compose service with a web container declaring
SERVICE_FQDN_WEB_3000: /.
- Set its domain to
https://app.example.com with port 3000 (stored as https://app.example.com:3000).
- Domains → Search engine indexing → Noindex → Save.
- Deploy. Inspect the generated compose labels /
curl -sD- -o /dev/null https://app.example.com/: no X-Robots-Tag.
Workaround (confirmed): clear the Port field on the domain and choose "Use This Port Anyway". The routing port still resolves to 3000 via getRequiredPort(), the portless domain now matches the portless flag, and after redeploy the X-Robots-Tag: noindex, nofollow header is present.
Other resources with a port in their domain will silently lose their noindex header on their next deploy after upgrading.
Coolify Version
v4.3.23 (last known good: v4.3.10; regression introduced by the withoutPort change first shipped in v4.3.15)
Are you using Coolify Cloud?
No (self-hosted)
Description and Error Message
On a Docker Compose service whose domain includes a port (e.g.
https://app.example.com:3000, as produced bySERVICE_FQDN_WEB_3000), setting Search engine indexing → Noindex has no effect: after a deploy the generated Traefik labels contain noX-Robots-Tagmiddleware, and responses carry noX-Robots-Tagheader. No error is logged.This worked on v4.3.10 and stopped working after upgrading to v4.3.23. The two sides of the noindex comparison normalize domains differently:
HasNoindexDomains::noindexDomains()strips the port vianormalizeNoindexDomain()→DomainPortOverrides::withoutPort()(HasNoindexDomains.php#L74-L76). This was added in v4.3.15. The stored flag becomeshttps://app.example.com.isNoindexDomain()normalizes only withValidationPatterns::normalizeApplicationDomainUrl(), which keeps the port (docker.php#L537-L546).fqdnLabelsForTraefik()callsisNoindexDomain($domain, …)with the raw domain, port included (docker.php#L759; same for Caddy at L585). For service applications$domaincomes fromServiceApplication::fqdns(), a plainexplode(',', $this->fqdn).So
https://app.example.com:3000is compared againsthttps://app.example.com, never matches, and the middleware is never emitted.Re-saving the domain in the UI does not help: the save still stores
fqdnwith the embedded port (https://app.example.com:3000) whilenoindex_domainsis stored portless.Expected Behavior
X-Robots-Tag: noindex, nofollowmiddleware regardless of whether its stored FQDN includes a port.isNoindexDomain(), wrap both normalizations inDomainPortOverrides::withoutPort()(or reuse the trait'snormalizeNoindexDomain()logic).Steps to Reproduce
SERVICE_FQDN_WEB_3000: /.https://app.example.comwith port3000(stored ashttps://app.example.com:3000).curl -sD- -o /dev/null https://app.example.com/: noX-Robots-Tag.Workaround (confirmed): clear the Port field on the domain and choose "Use This Port Anyway". The routing port still resolves to 3000 via
getRequiredPort(), the portless domain now matches the portless flag, and after redeploy theX-Robots-Tag: noindex, nofollowheader is present.Other resources with a port in their domain will silently lose their noindex header on their next deploy after upgrading.
Coolify Version
v4.3.23 (last known good: v4.3.10; regression introduced by the
withoutPortchange first shipped in v4.3.15)Are you using Coolify Cloud?
No (self-hosted)