Skip to content
intermediate Phase 2 · Docker Networking

Container DNS & Discovery

Use Docker DNS for service discovery and container name resolution.

45m
0 problems
Topic Progress 0%

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:

  1. The query first hits Docker's embedded DNS at 127.0.0.11
  2. Docker checks if the name matches a container on the same network
  3. If matched, Docker returns the container's IP address
  4. 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:

  1. Docker's embedded DNS checks container names on the same network
  2. Docker's embedded DNS checks network aliases on the same network
  3. If not found, Docker forwards to upstream DNS (configured via --dns or daemon.json)
  4. 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