How to Configure DNS Resolution for Containers with Custom Domains

The Apple Container toolchain enables custom domain resolution through an embedded DNS server that creates macOS resolver files in /etc/resolver and appends configured domains to container hostnames.

The apple/container repository provides a container runtime with built-in DNS resolution capabilities. By leveraging the DNSConfig struct defined in ContainerSystemConfig.swift, you can configure DNS resolution for containers with custom domains that resolve to container IP addresses from the host system.

Understanding the DNS Architecture

The DNS configuration resides in the top-level ContainerSystemConfig struct located in Sources/ContainerPersistence/ContainerSystemConfig.swift. This struct contains a dns property that instantiates DNSConfig, which stores the optional custom domain for container hostname resolution.

final public class DNSConfig: Codable, Sendable {
    public let domain: String?                 // ← the custom domain, if any

}

When the runtime loads configuration from config.toml or CLI flags, it uses the domain value to perform two critical operations: creating a macOS resolver file under /etc/resolver that forwards queries to the embedded DNS service listening on 127.0.0.1, and appending the domain suffix to container hostnames (e.g., transforming my-web-server into my-web-server.test).

Setting Up the macOS Resolver File

Before containers can resolve custom domains, you must create a resolver file that tells macOS to forward DNS queries for your specific domain to the container's embedded DNS server.

Create the resolver file using privileged commands:

sudo mkdir -p /etc/resolver
echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/test

This configuration directs all queries for the .test domain to the embedded DNS service running on localhost. The file path /etc/resolver/test corresponds to the domain name you intend to use.

Configuration Methods

You can specify the custom DNS domain using either CLI flags or the configuration file. Both methods interact with the DNSConfig struct's domain property.

Using the Command Line Interface

The runtime exposes specific flags for DNS configuration as documented in docs/command-reference.md:

  • --dns <ip>: Sets the DNS nameserver IP address (defaults to 127.0.0.1)
  • --dns-domain <domain>: Defines the custom domain appended to container hostnames
  • --dns-search <domain>: Adds a search suffix for the host's resolver

Launch a container with a custom domain:

container run --dns-domain test --name my-service my-image

Using the Configuration File

For persistent configuration, add a [dns] section to your config.toml file as documented in docs/container-system-config.md:

[dns]
domain = "test"

When specified in config.toml, all containers launched by the runtime automatically receive the configured domain suffix without requiring CLI flags.

Practical Implementation Workflow

Follow this complete workflow to enable and verify custom domain resolution:

  1. Create the resolver file (requires sudo):

    sudo mkdir -p /etc/resolver
    echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/dev
  2. Launch the container with the custom domain:

    container run --dns-domain dev --name my-web-server my-image
  3. Verify DNS resolution from the host:

    ping my-web-server.dev

    The ping should resolve to the container's IP address, confirming that the host resolver forwards queries to the embedded DNS.

  4. Clean up when finished:

    sudo rm /etc/resolver/dev

    Remove the resolver file to disable DNS resolution for that domain.

Summary

  • The DNSConfig struct in ContainerSystemConfig.swift stores the optional custom domain for container DNS resolution.
  • The runtime creates macOS resolver files under /etc/resolver to forward domain queries to the embedded DNS server at 127.0.0.1.
  • Use --dns-domain flag for ad-hoc configuration or the [dns] section in config.toml for persistent settings.
  • Container hostnames automatically append the custom domain suffix (e.g., container-name.custom-domain).

Frequently Asked Questions

Where does the container runtime store DNS configuration?

The DNS configuration is stored in the DNSConfig class within Sources/ContainerPersistence/ContainerSystemConfig.swift. This class contains a single optional domain property that specifies the default DNS domain appended to container hostnames. The runtime populates this property from either config.toml or CLI flags when the container system initializes.

What is the default address for the embedded DNS server?

According to the command reference in docs/command-reference.md, the embedded DNS server listens on 127.0.0.1 by default. You can override this using the --dns flag when launching containers, though the resolver file in /etc/resolver must point to the same address for host-side resolution to function.

How do I remove a custom DNS domain configuration?

To remove a custom domain, delete the corresponding resolver file from /etc/resolver/ using sudo privileges. For example, sudo rm /etc/resolver/test removes the .test domain configuration. As documented in examples/container-machine-vscode/README.md, this cleanup step prevents the host from attempting to resolve stale domain names after you stop using the container runtime.

Can I configure multiple custom DNS domains simultaneously?

The DNSConfig struct currently supports a single optional domain field. However, you can manually create multiple resolver files in /etc/resolver/ for different domains (e.g., /etc/resolver/dev and /etc/resolver/staging), each pointing to 127.0.0.1. You would then launch containers with the appropriate --dns-domain flag for each specific domain you want to use.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →