How to Set Up Local DNS Domains for Containers Using `container system dns` Commands
The container CLI provides built-in system dns subcommands to create, list, and delete persistent DNS domains that are automatically resolved inside every container via the system configuration file.
The container tool from the Apple container repository includes a native DNS configuration service that eliminates the need for manual resolver configuration. By using the container system dns commands, you can define custom domains in the system configuration file that propagate automatically to all containers. This article explains how to manipulate these DNS settings using the CLI and how the runtime applies them based on the source code in Sources/Services/RuntimeLinux/Server/RuntimeService.swift and Sources/Services/ContainerAPIService/Client/Flags.swift.
Understanding the DNS Architecture
The DNS system in container consists of three primary components that work together to provide persistent, system-wide resolution.
System Configuration Storage
All DNS domains are stored in the container-system-config.toml file under the [dns] section. This configuration defines the default DNS domain, nameservers, search domains, and resolver options. According to the repository documentation in docs/container-system-config.md, this file serves as the single source of truth for DNS settings across the container runtime.
Runtime DNS Injection
When a container starts, the runtime service reads the system configuration and injects the DNS settings into the container's resolv.conf. The implementation in Sources/Services/RuntimeLinux/Server/RuntimeService.swift handles this injection automatically. If the nameserver list is empty, the code falls back to the host's resolver (lines 218-224).
CLI Flag Processing
The command-line interface validates DNS-related flags in Sources/Services/ContainerAPIService/Client/Flags.swift. This parser prevents contradictory usage of --no-dns alongside other DNS flags and merges user-provided settings with the system configuration via helper functions in Sources/Services/ContainerAPIService/Client/Utility.swift.
Creating Local DNS Domains
Use the container system dns create command to register a new domain that resolves within all containers.
The command accepts a domain name and an optional --localhost IP address (defaulting to 127.0.0.1). When executed, it updates the [dns] section of container-system-config.toml and restarts the DNS resolver service.
# Create a domain resolving to the default localhost
sudo container system dns create myapp.local
# Bind to a specific IP address
sudo container system dns create myapp.local --localhost 203.0.113.113
After creation, the domain becomes instantly resolvable from all containers as myapp.local. (the resolver automatically appends the trailing dot).
Listing and Deleting DNS Domains
Manage existing domains using the list and delete subcommands.
Listing Configured Domains
The list (or ls) command displays all custom domains and their associated localhost IPs:
container system dns list
Typical output:
DOMAIN LOCALHOST
myapp.local 127.0.0.1
dev.test 203.0.113.113
Removing Domains
The delete (or rm) command removes entries from the system configuration:
sudo container system dns delete myapp.local
Once deleted, containers can no longer resolve the domain.
Per-Container DNS Overrides
While system DNS provides global defaults, you can override settings for individual containers using flags with container run.
These flags supplement or override the system-wide configuration:
container run \
--dns 1.1.1.1 \
--dns-domain example.com \
--dns-search corp.example.com \
--dns-option ndots:2 \
myimage:latest
To disable DNS entirely for a specific container:
container run --no-dns myimage:latest
Important: The validation logic in Flags.swift (lines 351-359) aborts execution if you combine --no-dns with any other DNS-related flags.
Edge Cases and Validation Rules
Understanding these constraints prevents configuration errors.
- Flag Conflicts: Using
--no-dnswith--dns,--dns-domain,--dns-search, or--dns-optiontriggers a CLI error. Use either--no-dnsor DNS flags, never both. - Empty Nameserver Fallback: If you clear all nameservers in the configuration,
RuntimeService.swift(lines 218-224) automatically falls back to the host's resolver. - Domain Collisions: Creating a domain that already exists overwrites the previous entry. Always verify existing domains with
container system dns listbefore creating new ones. - Non-Local IP Risks: Specifying a non-local IP with
--localhostbreaks DNS queries inside containers. Keep the IP within the container's network range, typically127.0.0.1or the VM's loopback address.
Summary
- The
container system dnscommand manages persistent DNS domains incontainer-system-config.toml. - The
create,list, anddeletesubcommands provide full CRUD operations for local DNS domains. - Runtime injection in
RuntimeService.swiftautomatically propagates DNS settings to every container'sresolv.conf. - The CLI validates flag combinations in
Flags.swift, preventing--no-dnsconflicts. - Per-container overrides using
--dns*flags merge with system defaults viaUtility.swift.
Frequently Asked Questions
Where are DNS domains stored in the container system?
DNS domains are stored in the container-system-config.toml file under the [dns] section. This file persists across daemon restarts and applies globally to all containers managed by the container tool.
Can I use --no-dns with other DNS flags?
No. The CLI parser in Flags.swift explicitly forbids combining --no-dns with any --dns, --dns-domain, --dns-search, or --dns-option flags. You must choose between disabling DNS entirely or configuring specific DNS settings.
What happens if I don't specify a nameserver in the system config?
If the nameserver list is empty, the runtime code in RuntimeService.swift (lines 218-224) automatically falls back to using the host system's resolver. However, explicitly setting at least one nameserver is recommended for predictable behavior.
Do DNS changes require restarting containers?
No. When you use container system dns create or delete, the command restarts the DNS resolver service automatically. New containers pick up these changes immediately, though running containers may need to be restarted to see updates depending on how they cache DNS configuration.
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 →