Docker DNS
Docker's embedded DNS server (127.0.0.11) that runs inside every container on a user-defined network, resolving container names and network aliases to IP addresses without any manual configuration.
Docker DNS — How Containers Find Each Other by Name
What Is Docker DNS in Simple Terms?
When a container wants to reach another container, it needs to know its IP address. But container IPs change every time a container restarts. Docker's embedded DNS server solves this — it automatically assigns each container a DNS hostname matching its container name, and updates the DNS record every time the container restarts with a new IP.
Containers use Docker DNS automatically on user-defined networks. On the default bridge network, there is no DNS — containers are on their own.
How Docker DNS Works
# Create user-defined networkdocker network create payment-network # Run containers on itdocker run -d --name api --network payment-network node:20-alpine sleep 3600docker run -d --name db --network payment-network postgres:15 \ -e POSTGRES_PASSWORD=secret # Check DNS config inside the containerdocker exec api cat /etc/resolv.conf# nameserver 127.0.0.11 <- Docker's embedded DNS# options ndots:0 # Resolve db by namedocker exec api nslookup db# Server: 127.0.0.11# Name: db# Address: 172.18.0.3 # Restart db — it gets a new IPdocker restart dbdocker exec api nslookup db# Name: db# Address: 172.18.0.4 <- updated automaticallyDNS in Docker Compose
version: "3.8"services: payment-api: environment: DB_HOST: postgres # service name = DNS hostname REDIS_HOST: redis # works automatically in Compose postgres: image: postgres:15 redis: image: redis:7-alpine# Compose auto-creates a user-defined network# All services resolve each other by service nameNetwork Aliases
# Give a container additional DNS namesdocker run -d \ --name postgres-primary \ --network app-network \ --network-alias db \ --network-alias database \ postgres:15 -e POSTGRES_PASSWORD=secret # Now reachable by three names:# postgres-primary, db, databasedocker exec api ping db # worksdocker exec api ping database # worksDefault Bridge Has No DNS
# Default bridge — no DNSdocker run -d --name web nginxdocker run -d --name api node:20-alpine sleep 3600 docker exec api nslookup web# ping: bad address 'web' <- FAILS — no DNS on default bridge # Fix: create user-defined networkdocker network create app-networkdocker network connect app-network webdocker network connect app-network apidocker exec api nslookup web # now worksQuick Reference & Troubleshooting Commands
| Problem | Cause | Fix |
|---|---|---|
nslookup fails inside container |
On default bridge network | Create and use a user-defined network |
| Name resolves to stale IP | Client cached old resolution | Restart the calling container or lower TTL expectations |
| Two containers can't resolve each other | On different networks | docker network connect <network> <container> |
| Alias not resolving | Alias set after container started | Aliases apply at connect time; reconnect the container with --alias |
| Compose service name unresolvable | Service on different Compose project network | Ensure both services are in the same docker-compose.yml or share a network |
TipAlways create a user-defined bridge network for any multi-container application. The one-line command
docker network create app-networktakes seconds and immediately gives you DNS, better isolation, and stable container-name resolution.
RememberThe default bridge network has no DNS — containers can only find each other by IP address, which changes on every restart. User-defined bridge networks automatically provide DNS resolution by container name.
Common MistakeHardcoding container IP addresses in application configuration. Container IPs change on every restart. Always use container names (on user-defined networks) or service names (in Compose) — Docker DNS resolves them to the current IP automatically.
SecurityDocker's embedded DNS server only resolves names within the same Docker network. Containers on separate networks cannot resolve each other's names even if they happen to know an IP — treat separate networks as a real isolation boundary, not just a naming convenience.
Frequently Asked Questions
Why can't containers resolve each other by name on the default bridge network?
Docker's embedded DNS server at 127.0.0.11 only activates automatic name resolution for containers on a user-defined network — the default `bridge` network Docker creates on install doesn't get this treatment for legacy compatibility reasons, and containers there can only reach each other by IP or via the deprecated `--link` flag. This is one of the main reasons Docker docs recommend always creating a custom network (or using Compose, which creates one automatically) rather than relying on the default bridge.
What's a common DNS-related mistake in multi-network container setups?
Assuming a container can resolve another container by name across two different Docker networks it isn't attached to — the embedded DNS server only resolves names within the same network, so a container needs to be explicitly connected to every network whose members it needs to reach by name. Also, container name resolution changes on restart if you don't use a fixed network alias, since the embedded DNS keys off the container's current name and network membership, not a stable identifier.