How to Fix "DNS lookup failed inside Docker container"
Quick answer
The "DNS lookup failed inside Docker container" issue occurs when containers cannot resolve external domain names or internal container hostnames through...
The "DNS lookup failed inside Docker container" issue occurs when containers cannot resolve external domain names or internal container hostnames through network name resolution. When a container attempts to make outbound HTTP requests, fetch packages, or connect to external APIs, requests time out with domain name resolution exceptions. This typically stems from mismatches between host system resolution daemons (like systemd-resolved) and Docker's embedded DNS engine.
The Problem
Running commands inside a container that rely on domain resolution (such as curl, apt-get, or ping) fail continuously with name resolution errors:
$ docker run --rm alpine ping google.com
ping: bad address 'google.com'
In application runtimes (such as Node.js or Python), error traces highlight DNS lookup failures explicitly:
Error: getaddrinfo ENOTFOUND api.github.com
at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:107:26) {
errno: -3008,
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'api.github.com'
}
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='api.stripe.com', port=443): Failed to establish a new connection: [Gaierror -3] Temporary failure in name resolution
Why It Happens
Docker containers use an embedded DNS server located at local IP 127.0.0.11. When a container queries external hostnames, 127.0.0.11 forwards the request to the nameservers listed in the host's /etc/resolv.conf file. Common breakdown causes include:
- Systemd-resolved Loopback Addresses: Modern Linux distributions (Ubuntu/Debian) use
127.0.0.53in host/etc/resolv.conf. Docker ignores local loopback addresses to prevent routing loops, defaulting to fallback Google DNS (8.8.8.8/8.8.4.4), which may be blocked on corporate firewalls. - VPN Network Overrides: Corporate VPN software alters host DNS configurations, causing container DNS requests routed to external resolvers to fail.
- Custom Bridge Subnet Conflicts: Custom Docker networks overlap with local physical network subnets, blocking routing to local DNS servers.
The Fix
Configure Docker globally to use reliable public or local upstream DNS servers explicitly.
Step 1: Set global DNS servers in daemon.json
Edit or create the Docker daemon configuration file at /etc/docker/daemon.json on your Linux host:
sudo nano /etc/docker/daemon.json
Add explicit upstream DNS servers (such as Google DNS 8.8.8.8 and Cloudflare DNS 1.1.1.1, or your corporate internal DNS IP addresses):
{
"dns": ["8.8.8.8", "1.1.1.1"]
}
Save the file and restart the Docker daemon:
sudo systemctl restart docker
Step 2: Configure custom DNS per container or Compose service
If you prefer setting DNS per service without changing global settings, specify the dns array in docker-compose.yml:
version: '3.8'
services:
app:
image: node:20-alpine
dns:
- 8.8.8.8
- 1.1.1.1
command: node index.js
Or using the Docker CLI:
docker run --rm --dns 8.8.8.8 alpine ping google.com
Step 3: Fix host systemd-resolved integration
If running Ubuntu, point Docker to the actual upstream NetworkManager/systemd-resolved file rather than the local stub file by creating a symlink or overriding options:
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
sudo systemctl restart docker
Still Not Working?
If DNS resolution continues to fail on Linux host environments, check your host's iptables firewall rules. Security tools like ufw or firewalld often block forwarding from Docker bridge interfaces (docker0) to the primary network interface.
Allow forwarding traffic in ufw:
sudo ufw default allow routed
sudo ufw reload
Verify DNS resolution inside a fresh container:
docker run --rm alpine nslookup google.com