How to Configure DNS Resolution for Containers: Per-Container and System-Level Guide

Configure DNS resolution for containers using per-container flags (--dns, --dns-search) for individual resolver settings, or use container system dns create and the [dns] TOML section to define host-side domains that enable cross-resolution between macOS and containers.

The apple/container framework provides flexible DNS resolution through two distinct configuration scopes. You can define nameservers for individual containers at runtime, or establish system-wide DNS domains that allow bidirectional name resolution between the macOS host and containers.

Per-Container DNS Configuration

Runtime DNS settings are applied via command-line flags when creating or running containers. The CLI parses these arguments in Sources/Services/ContainerAPIService/Client/Flags.swift and stores them in a ContainerConfiguration.DNSConfiguration object defined in Sources/ContainerResource/Container/ContainerConfiguration.swift.

The following flags control per-container resolution:

  • --dns <ip>: Specify one or more nameserver IP addresses
  • --dns-domain <domain>: Set the domain name for the container
  • --dns-option <opt>: Pass resolver options to the container
  • --dns-search <domain>: Define search domains for short hostname lookups

These settings are applied to the container's resolver when the runtime launches the container, as implemented in Sources/Services/RuntimeLinux/Server/RuntimeService.swift.

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

System-Level DNS Configuration

For persistent DNS settings that apply across all containers and enable host-to-container resolution, the framework supports system-level configuration through TOML files and CLI commands.

Configuring the DNS Domain in TOML

The ~/.config/container/config.toml file defines global DNS behavior. The [dns] section is decoded into ContainerSystemConfig via Sources/ContainerPersistence/ContainerSystemConfig.swift, which instantiates a DNSConfig object:

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

Add the following to your configuration file:

[dns]
domain = "test"

This appends .test to all container hostnames, making my-web-server resolvable as my-web-server.test from the host.

Creating Host-Side Resolver Entries

The container system dns create command establishes macOS resolver entries under /etc/resolver/. This requires sudo privileges and configures the macOS DNS cache to forward queries for the specified domain to the container's virtual network.

When combined with --localhost <ipv4>, this creates A records pointing to the host, enabling containers to reach host services.

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

Verify the resolver entry:

scutil --dns | grep host.container.internal

List all configured domains:

container system dns list

Implementation Architecture

The DNS configuration system relies on three primary components:

Summary

  • Use --dns flags for temporary, container-specific resolver settings that override defaults
  • Edit ~/.config/container/config.toml to set a default domain suffix for all container hostnames
  • Run sudo container system dns create to enable host-to-container DNS resolution via /etc/resolver/ entries
  • Include --localhost when creating system DNS entries to expose host services to containers at a specific IP address

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. Multiple --dns flags are supported for redundancy. These values populate the ContainerConfiguration.DNSConfiguration object used by the runtime when starting the container.

Where does the system store global DNS domain configuration?

Global settings are stored in ~/.config/container/config.toml under the [dns] section. The framework decodes this into DNSConfig as defined in Sources/ContainerPersistence/ContainerSystemConfig.swift, applying the domain suffix to all containers.

Why does container system dns create require sudo?

The command writes resolver configuration files to /etc/resolver/ and registers the domain with the macOS DNS cache, both of which require elevated privileges. This enables the host to resolve container hostnames using the configured domain suffix.

How can containers access services running on the macOS host?

Create a system DNS entry with the --localhost flag: sudo container system dns create host.container.internal --localhost 203.0.113.113. This maps the domain to the specified IPv4 address, allowing containers to reach host services via that hostname instead of using the bridge IP.

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 →