Add Dns To Docker Container

Add Dns To Docker Container

Reading time1 min
#Docker#Networking#Containers#DNS#DockerCompose#DevOps

Custom DNS in Docker: Practical Engineering Control Over Container Name Resolution

Developers often encounter erratic connectivity between Docker containers—especially in multi-tier or service-mesh setups where internal hostnames must resolve reliably. The culprit is frequently Docker’s default DNS configuration, which simply injects the host’s /etc/resolv.conf into each container. This works until it doesn’t.

Consider a deployment where a microservice references api.internal.local. If the host’s DNS can’t resolve this, containers will fail silently, generating logs like:

curl: (6) Could not resolve host: api.internal.local

Rather than chasing intermittent failures, take explicit control.


DNS Behavior in Docker: What Actually Happens?

  • On Linux, Docker Engine (tested with 20.10.x–24.0.x) defaults to copying /etc/resolv.conf into the container at runtime.
  • Containers join a user-defined bridge or overlay network; DNS queries typically route via a Docker internal DNS server (typically 127.0.0.11 for bridge networks).
  • This internal DNS is fast but can’t resolve anything outside the upstream nameservers it’s given.

Edge case: With Mac/Windows Docker Desktop, networking is virtualized—DNS behavior can vary; always inspect /etc/resolv.conf before assuming.


Injecting Custom DNS: Approaches Compared

1. Per-Container DNS Overrides (docker run --dns)

Force a container to use known, reliable DNS servers:

docker run --dns 10.100.10.53 --dns 8.8.4.4 --rm -it ubuntu:22.04 bash

Check the result:

cat /etc/resolv.conf

Sample output:

nameserver 10.100.10.53
nameserver 8.8.4.4

Note: If the upstream DNS is unreachable within the container’s virtual network, resolution will still fail.

2. Specify Search Domains (--dns-search)

For environments relying on unqualified hostnames or split DNS zones:

docker run --dns-search corp.acme.net -it --rm ubuntu:22.04 bash

This appends corp.acme.net to unqualified lookups, meaning ping db01 attempts db01.corp.acme.net.

Combine both flags when required:

docker run --dns 172.30.0.2 --dns-search dev.internal --rm -it debian:12 bash

3. Docker Compose Integration

Compose files formalize configuration for CI/CD pipelines—no room for mistakes or implicit defaults.

Example docker-compose.yml:

version: "3.8"
services:
  backend:
    image: registry.local/backend:2.12
    dns:
      - 10.1.2.3
      - 1.1.1.1
    dns_search:
      - devteam.local

Deploy:

docker compose up -d

Gotcha: Each time you update your compose file, running docker compose down && docker compose up -d ensures all containers inherit the new DNS config (restart alone won’t always reload /etc/resolv.conf).


Global Docker Daemon DNS

Some environments require every container—legacy and new—to use a specific set of resolvers. Update /etc/docker/daemon.json:

{
  "dns": ["172.20.30.40", "8.8.8.8"]
}

Apply changes:

sudo systemctl restart docker

Known issue: Daemon restarts will disrupt existing containers, albeit briefly. Batch restarts during maintenance.


Validation and Troubleshooting

Troubleshoot before assuming correctness:

  1. Shell Into Running Container:

    docker exec -it app_container bash
    
  2. Examine /etc/resolv.conf:
    Check nameserver entries precisely match configuration.

  3. Test DNS Resolution:

    apt update && apt install -y dnsutils
    dig backend1.devteam.local @10.1.2.3
    ping google.com
    
  4. If resolution fails:

    • Confirm container network can access specified nameservers (nmap -p 53 10.1.2.3).
    • Verify that security groups, Docker bridge/overlay settings, and upstream DNS ACLs are not blocking traffic.

Side note: For complex Kubernetes workloads, consider CoreDNS customization instead; Docker DNS settings won’t always propagate through orchestration layers.


Tip: Using Environment Variables For Dynamic DNS (Non-Obvious)

For advanced cases—such as ephemeral CI runners—you can interpolate DNS servers via environment variables and a small entrypoint script to write /etc/resolv.conf before starting the main process. This approach bypasses Docker’s own config but gives bleeder-edge flexibility (with risk).


Final Considerations

DNS misconfiguration is rarely obvious but often catastrophic, especially with containers distributed across environments—cloud, local VMs, hybrid. Explicitly set DNS at the right level (container, compose, or daemon) after careful inventory of network topology.

Alternate approach: some teams run in-container dnsmasq forwarding outbound requests, but that’s another set of tradeoffs—monitor resolver logs for blind spots.

No universal best answer exists, but defaulting to Docker’s out-of-the-box DNS is rarely sufficient for production-grade deployments. Take control, verify in the shell, and document any DNS layer outside Docker that could intercept queries.


Quick Reference Table

MethodScopeBest ForCommand/Config
--dns, --dns-searchSingle containerOne-off troubleshootingdocker run ...
dns, dns_search in YMLApplicationMulti-container stacksdocker compose ...
Daemon JSONHost-wideEnforced org-wide policy/etc/docker/daemon.json

When a container's network misbehaves, DNS is often the first layer worth auditing—before blaming application code or cloud providers.