feat(service): set and diff per-container service hostnames via urls (#72 item 1) #81
No reviewers
Labels
No labels
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-triage
ready
release
scope:apply
scope:capture
scope:coolify-api
scope:fleet
scope:manifest
scope:secrets
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/cast#81
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/service-domains"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements #72 item 1 — "adopt service
urlson 4.1.2 now (biggest UI-step deletion available today)".The claim this refutes
desiredFromManifestdropped a service'sdomainsand warned that hostnames were a manual Coolify UI act, citing a re-checked "no flatdomainson a 4.1.2 service, on any route." The audit disproved it — the same failure mode #51 corrected for backups. The flat shape has no route; the per-container capability was there at 4.1.2 all along, verified at the source:POST /services/PATCH /services/{uuid}allowlisturls([{name,url}]);applyServiceUrlsmatchesurls[].nameto aServiceApplicationand sets itsfqdn(ServicesController.php:296,320,505,962+:45-135).GET /services/{uuid}does$service->load(['applications'])andremoveSensitiveDatadoes not hidefqdn(:736).What changed
Services now speak the same per-container vocabulary a dockercompose app does:
domains(dropped + warned)service_domains: { <container>: [url] }urlson create and updateGET /services/{uuid}→applications[].fqdn, compared every runservice_domainsjoinsdesiredDomainsOfCreatedomains: string[]is removed fromServiceSpec— it can't name which container a hostname belongs to, which is exactly whaturlsrequires.service_domainsis canonicalized (keys + each URL array sorted) on both the desired and live sides, so container ordering never causes false drift.diff/apply(one extra GET per service), like backups.Two limits, stated out loud
GET /services/{uuid}aborts rather than projecting empty and re-PATCHing the hostname forever (#12/#14/#17 discipline). Not a silent "not compared".applyServiceUrlsrollback), soservice_domainson a create is pre-flighted. (Cross-service conflict detection remains the documented subset the preflight always was.)inventory --emit-draftdoesn't make the per-service GET, so a drafted service's hostnames are still declared by hand — draft's UNCAPTURED note and semantics.md say so (same shape as backups).Migration (operator)
A manifest using the old flat service
domainsmust move toservice_domains, naming the container (discoverable from acast diffread-back or the Coolify UI). For the incubator's umami:Tests
serviceApiFields→urls;attachServiceDomainsprojection + fail-closed on unreachable/unrecognized;desiredFromManifestemits canonicalizedservice_domains+ diffs clean/drift;desiredDomainsOfCreateclaims a service create's domains; manifest/fixture updated.npm run checkclean · 514 tests pass.🤖 Generated with Claude Code