# How to Configure DNS to Access Host Services from a Container

> Learn how to configure DNS to access host services from a container using Apple Container's embedded DNS server. Resolve host IPs with custom domains for seamless connectivity.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-20

---

**Apple Container provides an embedded DNS server that maps custom domain names to host IP addresses, allowing containers to resolve and connect to services running on the host via friendly DNS names.**

The `apple/container` repository includes a built-in DNS resolution system that bridges the networking gap between macOS hosts and Linux containers. By configuring a custom DNS domain that points to a specific host IP address, you can access host-bound services from inside containers without hardcoding IP addresses or exposing ports externally.

## How the DNS Resolution System Works

The container runtime runs an embedded DNS server that intercepts DNS queries from containers and resolves custom domains to host-local IP addresses. When you register a domain using the CLI, the system writes a resolver file to `/etc/resolver` on macOS and updates an in-memory lookup table.

According to the source code in [`Sources/APIServer/LocalhostDNSHandler.swift`](https://github.com/apple/container/blob/main/Sources/APIServer/LocalhostDNSHandler.swift), the `LocalhostDNSHandler` class monitors the resolver directory using a `DirectoryWatcher`. When files change, it parses lines matching `localhostOptionsRegex` to build a `[DNSName: IPv4Address]` dictionary. This dictionary is used to answer DNS queries for custom domains, returning the mapped IP address to the requesting container.

The default domain suffix is controlled by `DNSConfig.defaultDomain` in [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift), which automatically appends the local search domain to container resolver configurations.

## Step-by-Step DNS Configuration

### Select a Safe IPv4 Address Range

Choose an IP address that will not conflict with real networks. Apple recommends using documentation blocks such as `203.0.113.0/24` (TEST-NET-3) or private ranges like `172.16.0.0/12`. Avoid using `127.0.0.1` directly, as this can cause routing issues within the container network namespace.

### Register the DNS Domain

Use the `container system dns create` command to map your chosen IP to a hostname:

```bash
sudo container system dns create <domain-name> --localhost <ipv4-address>

```

This command creates a resolver file under `/etc/resolver` on macOS and registers the mapping with the container's DNS server. The `LocalhostDNSHandler` immediately updates its internal routing table to answer queries for the new domain.

### Verify Container Resolution

Test the configuration by running a container that attempts to resolve the custom domain:

```bash
container run -it --rm alpine/curl curl http://<domain-name>:<port>

```

The container forwards DNS requests to the host's DNS server, which returns the configured IPv4 address. The request is then routed to the host service listening on that address.

## Complete Working Example

The following example demonstrates mapping a custom domain to a documentation-range IP address and accessing a Python HTTP server from within a container:

```bash

# Choose a non-conflicting IP from the documentation range

IP=203.0.113.113
DOMAIN=host.container.internal

# Register the domain with the container DNS service

sudo container system dns create ${DOMAIN} --localhost ${IP}

# Start a simple HTTP server on the host (binding to localhost)

mkdir -p /tmp/test && cd /tmp/test && echo "hello" > index.html
python3 -m http.server 8000 --bind 127.0.0.1

# From a container, fetch the page using the DNS name

container run -it --rm alpine/curl curl http://${DOMAIN}:8000

# Output: hello

```

To remove the DNS mapping when finished:

```bash
sudo container system dns delete ${DOMAIN}

```

## Key Implementation Files

The DNS functionality is implemented across several core components:

- **[`Sources/APIServer/LocalhostDNSHandler.swift`](https://github.com/apple/container/blob/main/Sources/APIServer/LocalhostDNSHandler.swift)** – Watches resolver files and answers DNS queries for locally created domains using the `DirectoryWatcher` and regex parsing.
- **[`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift)** – Defines `DNSConfig` and stores the `defaultDomain` used for automatic search domain configuration.
- **`/etc/resolver`** – The macOS directory where the CLI writes resolver files for system-wide DNS resolution.

## Summary

- **Apple Container uses an embedded DNS server** (`LocalhostDNSHandler`) to resolve custom domains to host IP addresses.
- **Use safe IP ranges** like `203.0.113.0/24` to avoid network conflicts when mapping host services.
- **Register domains** with `sudo container system dns create <domain> --localhost <ip>` to write resolver files and update the DNS table.
- **Containers automatically inherit** the local search domain from `DNSConfig.defaultDomain`, enabling immediate resolution without restarting the runtime.
- **Resolution is dynamic** – the `DirectoryWatcher` detects changes to `/etc/resolver` files and updates the in-memory DNS table without requiring service restarts.

## Frequently Asked Questions

### What IP addresses are safe to use for host DNS mapping?

Use documentation-range addresses like `203.0.113.0/24` (TEST-NET-3) or private network ranges such as `172.16.0.0/12`. These ranges are guaranteed not to conflict with public internet addresses and are specifically reserved for testing and documentation purposes.

### How does the container DNS server know when I add a new domain?

The `LocalhostDNSHandler` in [`Sources/APIServer/LocalhostDNSHandler.swift`](https://github.com/apple/container/blob/main/Sources/APIServer/LocalhostDNSHandler.swift) uses a `DirectoryWatcher` to monitor `/etc/resolver` for changes. When you run `container system dns create`, the CLI writes a new resolver file, triggering the handler to parse the file and update its in-memory `[DNSName: IPv4Address]` dictionary used for query responses.

### Where is the DNS configuration stored on macOS?

The `container system dns create` command writes resolver configuration files to `/etc/resolver`. macOS uses this directory to determine which DNS server should handle queries for specific domains. The container runtime reads these files to build its internal routing table.

### Can I delete a DNS mapping after creating it?

Yes. Use `sudo container system dns delete <domain-name>` to remove the resolver file and unregister the mapping from the embedded DNS server. The `DirectoryWatcher` detects the file deletion and immediately removes the entry from the in-memory lookup table, preventing further resolution of that domain.