macOS has a built-in mechanism for routing DNS queries to a particular resolver based on the domain suffix: drop a file into /etc/resolver/ and the system picks it up automatically. This page sets up docker. so every tool on your Mac (curl, ping, browsers, language clients) can resolve container names without passing @127.0.0.1 -p 1053 every time.
This assumes CoreDNS is already running on your Mac (see getting-started.md) and listening on 127.0.0.1:1053.
Create /etc/resolver/docker with a nameserver and port:
sudo mkdir -p /etc/resolver
sudo tee /etc/resolver/docker <<'EOF'
nameserver 127.0.0.1
port 1053
EOFWhy a file named docker? macOS reads every file in /etc/resolver/ and treats the filename as the domain it applies to. A file named docker routes queries for the docker. TLD; a file named internal.example routes queries for internal.example.. This is documented in the resolver(5) manpage.
Why nameserver + port? The resolver config uses BSD-style directives. nameserver is the IP of the DNS server and port is its port. macOS does not accept 127.0.0.1:1053 in a single line the way systemd-resolved does -- it needs the two keys on their own lines.
No restart is needed. macOS reads /etc/resolver/ on every lookup, so the change takes effect immediately.
Three commands confirm the routing is set up correctly.
1. Check that macOS picked up the file:
scutil --dns | grep -A3 dockerYou should see an entry like:
resolver #9
domain : docker
nameserver[0] : 127.0.0.1
port : 1053
2. Resolve through the macOS directory service:
dscacheutil -q host -a name web.dockerThis bypasses dig and asks macOS's own resolver the way everyday applications do. A successful lookup prints the name, IP, and the alias chain.
3. Sanity-check with dig:
dig web.docker @127.0.0.1 -p 1053 +shortIf this returns an IP but dscacheutil does not, the /etc/resolver/docker file was not picked up. Try sudo killall -HUP mDNSResponder to nudge the resolver.
macOS's /etc/resolver/ mechanism routes one TLD per file. If your Corefile serves several zones, create one resolver file per zone:
sudo tee /etc/resolver/docker <<'EOF'
nameserver 127.0.0.1
port 1053
EOF
sudo tee /etc/resolver/internal <<'EOF'
nameserver 127.0.0.1
port 1053
EOFWhy one file per zone? macOS only looks at the filename, so a single file cannot own multiple unrelated suffixes. This is different from systemd-resolved, which can list several Domains= entries in one drop-in. It is not a limitation of coredns-docker.
- CoreDNS not running. macOS routes queries based on the file, not the liveness of the server. If CoreDNS is down, resolver lookups hang until they time out. Use
lsof -iUDP:1053orss -ulnp | grep 1053on Linux to confirm the server is listening. - VPN resolvers shadowing your config. Corporate VPNs often install their own resolver files with higher priority.
scutil --dnswill show you every resolver macOS considers; if a VPN resolver claims thedocker.suffix, remove or edit its file. - Browsers with their own resolvers. Chrome and Firefox support DNS-over-HTTPS with their own resolver, bypassing macOS entirely. If browser lookups for
web.dockerfail whiledscacheutilsucceeds, disable Secure DNS in the browser's settings for testing.