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-dns with --dns, --dns-domain, --dns-search, or --dns-option triggers a CLI error. Use either --no-dns or 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 list before creating new ones.
  • Non-Local IP Risks: Specifying a non-local IP with --localhost breaks DNS queries inside containers. Keep the IP within the container's network range, typically 127.0.0.1 or the VM's loopback address.

Summary

  • The container system dns command manages persistent DNS domains in container-system-config.toml.
  • The create, list, and delete subcommands provide full CRUD operations for local DNS domains.
  • Runtime injection in RuntimeService.swift automatically propagates DNS settings to every container's resolv.conf.
  • The CLI validates flag combinations in Flags.swift, preventing --no-dns conflicts.
  • Per-container overrides using --dns* flags merge with system defaults via Utility.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:

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 →