Skip to content

feat(up): use Apple container DNS when domain registered, /etc/hosts fallback otherwise#97

Merged
Cyb3rDudu merged 2 commits into
Mcrich23:mainfrom
Cyb3rDudu:feat/dns-domain-resolution
Jun 30, 2026
Merged

feat(up): use Apple container DNS when domain registered, /etc/hosts fallback otherwise#97
Cyb3rDudu merged 2 commits into
Mcrich23:mainfrom
Cyb3rDudu:feat/dns-domain-resolution

Conversation

@Cyb3rDudu

Copy link
Copy Markdown
Collaborator

Closes #81

When a project's sanitized name is already registered via container system dns create, containers are named <svc>.<domain> and get --dns-domain so the daemon's DNS server resolves peers. The /etc/hosts cross-patcher is skipped on this path. When the domain isn't registered, behavior is unchanged — legacy dashed names, /etc/hosts patching, and a one-time note with the sudo command.

ComposeDown tries all candidate name shapes (legacy dashed, dotted DNS, explicit container_name) so teardown works regardless of which mode created the containers.

Changes:

  • sanitizeDnsDomain / dnsListContainsDomain — pure helpers for deriving a DNS label from the project name and checking registration
  • DNS detection in run() — shells out to container system dns list, sets dnsAvailable
  • configService() — passes --name <svc>.<domain> + --dns-domain when DNS is available
  • crossPatchHostsForService — /etc/hosts fallback, gated on !dnsAvailable
  • stopOldStuffByName + ComposeDown multi-shape cleanup

Tested with container 0.12.3 on macOS 26. Two alpine services with name: dnstest — dotted names resolve via getent, /etc/hosts untouched, resolv.conf carries the domain. Auto-skips when no domain is pre-registered.

Static tests: 11 tests covering sanitization rules and dns list parsing.
Dynamic test: end-to-end DNS path verification (skips gracefully without registered domain).

…fallback otherwise

When the project's sanitized name is already registered via
container system dns create, name containers <svc>.<domain> and pass
--dns-domain so the daemon serves DNS for peers. The /etc/hosts
cross-patcher is skipped on this path. Otherwise keep the legacy dashed
names + patcher unchanged, with a notice pointing at the sudo command.

ComposeDown now tries every candidate name shape (legacy, dotted,
explicit) so it cleans up containers from either mode.

Static tests cover sanitizeDnsDomain and dnsListContainsDomain.
Dynamic test verifies dotted naming, peer resolution via getent,
and that /etc/hosts is left untouched when DNS is available.
@Cyb3rDudu Cyb3rDudu force-pushed the feat/dns-domain-resolution branch from 9f2c630 to 1e42796 Compare May 29, 2026 08:40
@Mcrich23

Copy link
Copy Markdown
Owner

@Cyb3rDudu so sorry for the delay. Cleaning out the backlog right now, can you please resolve the conflicts with main?

Cyb3rDudu added a commit to Cyb3rDudu/Container-Compose that referenced this pull request Jun 30, 2026
Resolve ComposeUp.swift conflicts:
- getIPForRunningService: keep containerName(for:) helper, retain main's
  container-address comment (Mcrich23#100).
- waitUntilServiceIsRunning: adopt main's ActivityClock idle/maxWait
  signature (Mcrich23#112); keep containerName(for:) helper in place of the
  silent guard-let-projectName return.
- configService: keep BOTH Mcrich23#97's --dns-domain args and main's compose
  project/service labels (Mcrich23#110) — independent features at the same site.
- Failed-wait teardown: call stopExistingContainers([containerName]) (Mcrich23#97
  rename) instead of main's stopOldStuff([serviceName]); pass the actual
  launched name so dotted/explicit names are torn down correctly.

Builds clean; 63 static tests pass (DNS helpers, parsing, volumes, helpers).

Co-Authored-By: Claude <noreply@anthropic.com>
Resolve ComposeUp.swift conflicts:
- getIPForRunningService: keep containerName(for:) helper, retain main's
  container-address comment (Mcrich23#100).
- waitUntilServiceIsRunning: adopt main's ActivityClock idle/maxWait
  signature (Mcrich23#112); keep containerName(for:) helper in place of the
  silent guard-let-projectName return.
- configService: keep BOTH Mcrich23#97's --dns-domain args and main's compose
  project/service labels (Mcrich23#110) — independent features at the same site.
- Failed-wait teardown: call stopExistingContainers([containerName]) (Mcrich23#97
  rename) instead of main's stopOldStuff([serviceName]); pass the actual
  launched name so dotted/explicit names are torn down correctly.

Builds clean; 63 static tests pass (DNS helpers, parsing, volumes, helpers).
@Cyb3rDudu Cyb3rDudu force-pushed the feat/dns-domain-resolution branch from 5e3c395 to 9261ed3 Compare June 30, 2026 15:50
@Cyb3rDudu Cyb3rDudu merged commit 1f0641a into Mcrich23:main Jun 30, 2026
1 check passed
@Cyb3rDudu Cyb3rDudu deleted the feat/dns-domain-resolution branch June 30, 2026 16:03
Cyb3rDudu added a commit to thromel/Container-Compose that referenced this pull request Jun 30, 2026
Resolve ComposeUp.swift conflicts after Mcrich23#97 (DNS + compose labels +
ActivityClock idle wait + stopOldStuff->stopExistingContainers rename)
landed on main:

- Wait function: keep Mcrich23#119's waitUntilServiceStarted name, ServiceStartState
  return, and .stopped exit-code validation; adopt Mcrich23#97's ActivityClock
  idle/maxWait signature and containerName(for:) lookup.
- Run path: keep Mcrich23#119's detach (exit-code guard) vs attached (fire-and-forget
  Task) structure, threading an ActivityClock through both branches so the
  idle wait sees pull progress; keep Mcrich23#119's startState switch (healthcheck +
  dependency gating).
- Stop: keep Mcrich23#97's stopExistingContainers (container-name strings); drop
  Mcrich23#119's stopOldStuff (no remaining callers after the merge took Mcrich23#97's call
  sites).
- Instance state: keep both Mcrich23#119's serviceStartStates/serviceHealth and Mcrich23#97's
  serviceContainerNames.
- Helpers: keep both Mcrich23#119's run-arg/service-selection helpers and Mcrich23#97's
  containerName(for:).

Builds clean; 104 static tests pass (dependencies, healthcheck, networks,
parsing, volumes, entrypoint, helpers).

Follow-up: Mcrich23#97's runTask teardown-on-wait-failure is intentionally omitted —
it assumes a single wrapping runTask, which Mcrich23#119's detach/attached split
doesn't have. Worth re-adding once the run path is unified.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use Apple container's built-in DNS for inter-container resolution when domain is registered

2 participants