By default, containers inherit DNS configuration from the Docker daemon. When you need to override that, three directives give you full control: dns:, dns_search:, and dns_opt:.
Setting custom DNS servers
dns: overrides which resolvers the container queries:
services:
app:
image: myapp
dns:
- 1.1.1.1
- 8.8.8.8
The container now uses Cloudflare and Google DNS instead of whatever the host provides. Useful when:
- The host DNS is slow or unreliable for your use case
- You need a specific public DNS for content filtering (Pi-hole, NextDNS)
- A development environment must reach internal services through a corporate DNS server
Search domains
dns_search: adds search domains so short names resolve against them:
services:
app:
image: myapp
dns_search:
- corp.example.com
- internal.example.com
Now app can resolve database as database.corp.example.com (or database.internal.example.com) without using a fully qualified name. Convenient when working with internal services that share a parent domain.
Resolver options
dns_opt: passes options to the resolver library:
services:
app:
image: myapp
dns_opt:
- "ndots:2"
- "timeout:1"
- "attempts:2"
Common options:
ndots:N— names with fewer than N dots are looked up using search domains firsttimeout:N— seconds to wait for a DNS responseattempts:N— how many retries before giving uprotate— round-robin through the configured nameservers
A practical example
A development container that needs to resolve internal hostnames through a VPN’s DNS:
services:
dev-app:
image: myapp
dns:
- 10.0.0.1 # Corporate DNS reached over VPN
- 1.1.1.1 # Public fallback
dns_search:
- corp.example.com
dns_opt:
- "ndots:1"
- "timeout:2"
api, auth, and other internal hostnames resolve through corporate DNS via the search domain, while public DNS handles everything else.
dns vs extra_hosts
Easy to confuse, but very different:
dns:([Tip #65, this one]): tells the container which DNS server(s) to query. Affects how names are resolved.extra_hosts:(Tip #36): adds static entries to/etc/hosts. Bypasses DNS entirely for those specific names.
Use dns: when you want to change the resolver. Use extra_hosts when you want to pin a specific hostname to a specific IP regardless of DNS.
Verifying the configuration
Check what’s actually configured inside the container:
# See the resolved /etc/resolv.conf
docker compose exec app cat /etc/resolv.conf
# Test name resolution
docker compose exec app getent hosts api.corp.example.com
If your settings don’t appear, the Docker daemon’s default DNS may take precedence, or the image’s entrypoint may be rewriting /etc/resolv.conf.