Docker's Embedded DNS Server
Docker's Embedded DNS Server
Docker runs an embedded DNS server at 127.0.0.11 that handles name resolution for containers on user-defined networks. This provides built-in service discovery — containers can reach each other by name without knowing IP addresses.
How It Works
When a container performs a DNS lookup:
- The query first hits Docker's embedded DNS at
127.0.0.11 - Docker checks if the name matches a container on the same network
- If matched, Docker returns the container's IP address
- If not matched, Docker forwards to the configured upstream DNS servers
Container → 127.0.0.11 (Docker DNS) → Container IP (local)
→ Upstream DNS (external)
Resolv.conf in Containers
# Check DNS config inside container
docker exec web cat /etc/resolv.conf
nameserver 127.0.0.11
search my-network
options ndots:0
The 127.0.0.11 nameserver is Docker's embedded DNS. The search domain is the network name. ndots:0 prevents short names from being treated as FQDNs.
Default Bridge vs Custom Bridge
# Default bridge: NO embedded DNS
docker run -d --name web nginx
docker run -d --name api nginx
# On default bridge, web CANNOT resolve 'api'
docker exec web ping api
# ping: bad address 'api'
# Must use IP address
docker exec web ping 172.17.0.3
# Custom bridge: YES embedded DNS
docker network create mynet
docker run -d --name web --network mynet nginx
docker run -d --name api --network mynet nginx
# web CAN resolve 'api'
docker exec web ping -c 1 api
# PING api (172.19.0.3): 56 data bytes
# 64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.067 ms
This is why custom bridge networks are always recommended over the default bridge.
DNS Configuration Options
DNS Configuration Options
Set DNS per Container
# Use specific DNS servers
docker run -d --dns 8.8.8.8 --dns 8.8.4.4 myapp
# Add search domains
docker run -d --dns-search company.com myapp
# Set DNS options
docker run -d --dns-opt ndots:5 myapp
# Check result
docker exec myapp cat /etc/resolv.conf
# nameserver 8.8.8.8
# nameserver 8.8.4.4
# search company.com
# options ndots:5
Set DNS Globally (daemon.json)
{
"dns": ["8.8.8.8", "8.8.4.4"],
"dns-search": ["company.com"],
"dns-opts": ["ndots:5"]
}
This affects all containers unless overridden per-container.
Custom DNS per Network
# Create network with specific DNS
docker network create \
--dns 8.8.8.8 \
--dns 1.1.1.1 \
--dns-search internal.company.com \
my-network
# All containers on this network use these DNS settings
docker run -d --network my-network myapp
# /etc/resolv.conf contains 8.8.8.8 and 1.1.1.1
Host DNS Passthrough
# Use host's DNS settings (useful for corporate DNS)
docker run -d --network host myapp
# Uses /etc/resolv.conf from host directly
DNS Caching
Docker's embedded DNS does not cache results. Each DNS query goes to the upstream server. For applications with high DNS query rates, run a local DNS cache:
# Run dnsmasq as DNS cache
docker run -d --name dns-cache \
--network mynet \
-p 53:53/udp \
jpillora/dnsmasq \
--no-daemon --log-queries
# Point other containers to it
docker run -d --dns 172.19.0.2 --network mynet myapp
Internal DNS for Docker Compose
In Docker Compose, services automatically get DNS entries based on their service name:
services:
web:
image: nginx
networks:
- app-net
api:
image: myapi
networks:
- app-net
networks:
app-net:
driver: bridge
The web service can resolve api by name. This is Docker's embedded DNS in action.
Service Discovery with DNS
Service Discovery with DNS
Container Name Resolution
Each container gets a DNS A record for its name:
docker run -d --name my-database --network appnet postgres:16
# Other containers on appnet can resolve:
# my-database → 172.19.0.2
getent hosts my-database
Network Aliases
Aliases provide alternative DNS names for a container:
# Single container with multiple DNS names
docker run -d --name db \
--network appnet \
--network-alias primary-db \
--network-alias postgres \
postgres:16
# Now 'db', 'primary-db', and 'postgres' all resolve
docker exec web nslookup primary-db
Use Cases
Database failover:
# Primary
docker run -d --name db-primary \
--network appnet --network-alias db \
postgres:16
# Replica (if primary fails, alias switches)
docker run -d --name db-replica \
--network appnet --network-alias db-replica \
postgres:16
Service versions:
# v1
docker run -d --name api-v1 --network appnet --network-alias api myapi:v1
# v2
docker run -d --name api-v2 --network appnet --network-alias api-v2 myapi:v2
Reverse DNS (IP → Name)
Docker's DNS supports reverse lookups:
docker exec web nslookup 172.19.0.2
# Name: api
# Address: 172.19.0.2
DNS Resolution Order
When a container resolves a name:
- Docker's embedded DNS checks container names on the same network
- Docker's embedded DNS checks network aliases on the same network
- If not found, Docker forwards to upstream DNS (configured via
--dnsor daemon.json) - Upstream DNS checks search domains, then FQDN
# Resolution chain in /etc/resolv.conf
# nameserver 127.0.0.11 ← Docker DNS first
# search appnet ← search domains
# options ndots:0 ← treat single labels as names
Multi-Network DNS
A container on multiple networks can resolve names from any network it's connected to:
docker network connect frontend api
docker network connect backend api
# api can resolve names from both frontend and backend networks
docker exec api getent hosts web # frontend network
docker exec api getent hosts db # backend network