Configure Custom DNS Settings for Containers in Apple Container

You can configure custom DNS settings for containers using per-container --dns flags for temporary runtime overrides, or system-wide [dns] configuration in ~/.config/container/config.toml combined with container system dns commands for persistent host-to-container resolution.

Managing DNS resolution in containerized environments requires both flexibility and precision. The Apple Container project provides two distinct architectural layers for configuring custom DNS settings: per-container runtime configuration and system-wide domain management. This guide demonstrates both approaches using the actual implementation from the apple/container source code.

Per-Container DNS Configuration

Configure DNS settings for individual containers at runtime using command-line flags. This approach overrides system defaults for specific container instances without affecting global configuration.

Using Runtime DNS Flags

Pass DNS parameters directly to the container run or container create commands. The CLI parses these flags in [Sources/Services/ContainerAPIService/Client/Flags.swift](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/Flags.swift) and stores them in a ContainerConfiguration.DNSConfiguration object.

The following flags are available:

  • --dns <ip> – Specify nameserver IP addresses
  • --dns-search <domain> – Set DNS search domains
  • --dns-domain <domain> – Set the local domain name
  • --dns-option <opt> – Specify DNS resolver options

Apply custom nameservers to a single container:

container run --dns 8.8.8.8 --dns 1.1.1.1 \
    --dns-search example.com \
    alpine:latest

This configuration applies only to the launched container. The container's resolver queries 8.8.8.8 and 1.1.1.1 and appends example.com to bare hostnames. The runtime applies these settings in [Sources/Services/RuntimeLinux/Server/RuntimeService.swift](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift).

System-Wide DNS Configuration

Configure persistent DNS settings that apply across all containers and enable host-to-container name resolution using the system configuration file or the container system dns command group.

TOML Configuration File

Define default DNS domains in ~/.config/container/config.toml. The configuration is decoded into ContainerSystemConfig, which contains a dns property of type DNSConfig as defined in [Sources/ContainerPersistence/ContainerSystemConfig.swift](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift).

The DNSConfig class structure:

final public class DNSConfig: Codable, Sendable {
    public let domain: String?
    public init(domain: String? = nil) { self.domain = domain }
}

Add the [dns] section to your configuration file:

[dns]
domain = "test"

With this setting, my-web-server becomes reachable as my-web-server.test from the host. The container ls command displays the fully qualified hostname, and all containers receive this domain suffix by default.

Host-Side DNS Domains

Create local resolver entries for container-to-host communication using container system dns create. This command writes a resolver file under /etc/resolver/<domain> and registers the domain with the macOS DNS cache.

Enable containers to reach a service on the host:

sudo container system dns create host.container.internal \
    --localhost 203.0.113.113

The --localhost flag sets the IPv4 address that serves as the A record for the domain. Containers can now resolve http://host.container.internal:8000 to reach a host service listening on port 8000.

Verify the resolver entry:

scutil --dns | grep host.container.internal

List all configured system DNS domains:

container system dns list

How DNS Configuration Works Under the Hood

The architecture separates configuration storage from runtime application. Per-container settings are stored in ContainerConfiguration.DNSConfiguration (defined in [Sources/ContainerResource/Container/ContainerConfiguration.swift](https://github.com/apple/container/blob/main/Sources/ContainerResource/Container/ContainerConfiguration.swift)) and injected at container startup. System-wide settings persist in ContainerSystemConfig and translate to macOS resolver files under /etc/resolver.

This dual-layer approach ensures that DNS settings remain consistent whether applied dynamically at runtime or configured permanently in the TOML file.

Summary

  • Per-container DNS uses --dns, --dns-search, and related flags parsed by Flags.swift and applied via RuntimeService.swift for immediate, instance-specific overrides.
  • System-wide DNS leverages the [dns] section in ~/.config/container/config.toml, processed by ContainerSystemConfig.swift and the DNSConfig class, to set default domains for all containers.
  • Host resolution requires sudo container system dns create with optional --localhost to write resolver files under /etc/resolver, enabling bidirectional host-container communication.

Frequently Asked Questions

How do I set a custom DNS server for a single container?

Use the --dns flag with container run or container create. You can specify multiple nameservers by repeating the flag. For example: container run --dns 8.8.8.8 --dns 8.8.4.4 ubuntu:latest. These settings populate the ContainerConfiguration.DNSConfiguration struct and apply only to that specific container instance.

What is the difference between per-container and system-wide DNS configuration?

Per-container configuration modifies the resolver settings inside the container's network namespace at runtime and disappears when the container stops. System-wide configuration modifies the ContainerSystemConfig stored in ~/.config/container/config.toml and creates persistent macOS resolver entries under /etc/resolver, affecting how the host resolves container names and how containers resolve the configured domain.

How do I enable containers to resolve services running on the host?

Execute sudo container system dns create <domain> --localhost <host-ip> to create a local resolver entry. This writes a file to /etc/resolver/<domain> pointing to the specified IPv4 address. Containers can then resolve the domain to reach services bound to that IP on the host, such as host.container.internal:8080 for a local development server.

Where does Apple Container store DNS configuration data?

System-wide DNS settings are stored in the dns property of ContainerSystemConfig, which the framework reads from ~/.config/container/config.toml. The DNSConfig struct in Sources/ContainerPersistence/ContainerSystemConfig.swift defines this storage format, currently supporting an optional domain string. Per-container settings reside temporarily in ContainerConfiguration.DNSConfiguration within the container's runtime state.

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 →