How to Configure Custom DNS Domains for Container-to-Host Communication in Apple Container

Set the domain key in the [dns] section of your ~/.config/container/config.toml file to enable automatic DNS resolution for containers using the pattern <container-name>.<domain> or <container-id>.<domain> directly from the host.

The Apple Container runtime ships with a built-in DNS server that resolves hostnames of running containers on the host side. By configuring a custom DNS domain, you eliminate the need to manually edit /etc/hosts or remember raw container IDs when connecting to containers from the host system.

Understanding the DNS Configuration Structure

The domain configuration is defined in the Swift source code through a dedicated configuration type that maps directly to the TOML schema.

The DNSConfig Implementation

In Sources/ContainerPersistence/ContainerSystemConfig.swift, the DNSConfig struct holds the optional domain property:

final public class DNSConfig: Codable, Sendable {
    public let domain: String?          // DNS domain (e.g. "test")
    // ...
}

This structure (lines 34-39) defines the [dns] table in the configuration file. When the domain property contains a value, the runtime automatically appends it to every container's hostname and registers the fully-qualified name with the host's resolver.

Configuration Schema Documentation

The TOML schema is documented in docs/container-system-config.md (lines 47-52). The [dns] table accepts the following key:

Key Type Default Description
domain String? unset Local DNS domain appended to container hostnames

When unset, no domain suffix is appended, and only the raw container ID is resolvable.

Configuring the DNS Domain in config.toml

To configure custom DNS domains for container-to-host communication, create or modify the user configuration file at the standard path.

Creating the User Configuration File

Create the file ~/.config/container/config.toml with the following content:


# ~/.config/container/config.toml

[dns]
domain = "test"          # any string: "mycorp.local", "containers.internal", etc.

You can use any valid domain string, such as "mycorp.local", "containers.internal", or simple test domains like "test". The runtime uses this value to construct fully-qualified domain names for all running containers.

Configuration Loading Order

The configuration is loaded by ConfigurationLoader at startup, defined in Sources/ContainerPersistence/ConfigurationLoader.swift. The loader merges configurations from multiple locations in the following precedence order:

  1. User config: ~/.config/container/config.toml
  2. Application config
  3. Installation config

Settings in the user config file override values from lower-precedence locations. Changes to the DNS configuration take effect immediately on the next container runtime startup.

Resolving Container Hostnames from the Host

Once the domain is configured, the runtime automatically registers DNS entries for every container in the format <container-id>.<domain>.

Automatic Registration Patterns

When you start a container with a name, the runtime registers two DNS records:

  • <container-id>.<domain> — Always registered using the container's unique identifier
  • <container-name>.<domain> — Registered only when using the --name flag

For example, with domain = "test" set in your config:

container run --name my-web-server -p 8080:80 docker.io/library/nginx:latest

The container becomes reachable from the host as both my-web-server.test and <container-id>.test.

Testing DNS Resolution

Verify the DNS entries using standard networking tools:


# Query the named container

dig +short my-web-server.test

# Output: 192.168.100.42

# Query by container ID

dig +short <container-id>.test

# Output: 192.168.100.42

You can also use ping or curl to test connectivity:

ping my-web-server.test
curl http://my-web-server.test:8080

The host's resolver answers these queries with the container's actual IP address, allowing seamless integration with browsers, API clients, and development tools.

Disabling the Custom Domain

To disable the custom DNS domain and revert to resolving only by raw container ID, remove or comment out the domain line in your configuration:

[dns]

# domain = ""          # Disabled: only <container-id> is resolvable

Alternatively, set the value to an empty string. When disabled, the runtime does not append any domain suffix, and you must reference containers by their full ID string.

Summary

  • The DNS domain is configured in the [dns] section of ~/.config/container/config.toml using the domain key.
  • The configuration structure is defined in Sources/ContainerPersistence/ContainerSystemConfig.swift within the DNSConfig class.
  • When set, containers become resolvable as <container-name>.<domain> and <container-id>.<domain> from the host system.
  • The ConfigurationLoader (in Sources/ContainerPersistence/ConfigurationLoader.swift) loads user, app, and install configs in that precedence order.
  • No domain configuration results in bare container IDs only, requiring manual IP management for host communication.

Frequently Asked Questions

Where is the DNS configuration stored in the Apple Container source code?

The DNS configuration logic resides in Sources/ContainerPersistence/ContainerSystemConfig.swift (lines 34-39), where the DNSConfig class defines an optional domain: String? property. This Swift struct maps directly to the [dns] table in the TOML configuration file, as documented in docs/container-system-config.md.

What is the exact format for configuring a custom DNS domain?

The configuration uses TOML syntax. Create a file at ~/.config/container/config.toml containing a [dns] section with a domain key set to your desired domain string:

[dns]
domain = "mydomain.local"

Any valid string works as the domain value, and the runtime automatically appends it to container hostnames for resolution.

Can I use multiple DNS domains or subdomains simultaneously?

The current implementation supports only a single DNS domain value in the DNSConfig struct. The domain property is a single optional String, not an array. To use different domains for different containers, you must modify the configuration and restart the runtime between container launches, or use a single domain with descriptive container names.

How do I troubleshoot DNS resolution failures between containers and the host?

First, verify your ~/.config/container/config.toml contains the correct [dns] domain setting and that the runtime has been restarted since the change. Check that the container is running with container ps and confirm the name registration using dig +short <container-name>.<your-domain>. If queries fail, ensure your system's resolver is configured to use the container runtime's built-in DNS server, which listens on the host side for these specific domain queries.

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 →