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:
ContainerSystemConfig.swift: Defines theDNSConfigclass and TOML parsing logicContainerConfiguration.swift: Stores per-containerDNSConfigurationobjectsRuntimeService.swift: Applies DNS settings when launching containers
Summary
- Use
--dnsflags for temporary, container-specific resolver settings that override defaults - Edit
~/.config/container/config.tomlto set a default domain suffix for all container hostnames - Run
sudo container system dns createto enable host-to-container DNS resolution via/etc/resolver/entries - Include
--localhostwhen 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →