Skip to content

Docker DNS Forwarder is a lightweight tool that enables the host machine to resolve Docker container names to their IPs via domains in the format "container-name.custom-suffix" (e.g., ".docker")

License

Notifications You must be signed in to change notification settings

bytesharky/docker-dns

Repository files navigation

Docker DNS Forwarder: Resolve Container Names to IPs on Host Machine

In Docker, containers can typically access each other by their container names (relying on Docker's built-in DNS at 127.0.0.11). However, the host machine cannot resolve container names by default.

This tool —— the Docker DNS Forwarder , solves this problem: it allows the host to access container services directly using domain names in the format container-name.custom-suffix, no port mapping required, no hosts file modification needed.

Read this in other languages

English

中文,Chinese

✨ Feature Highlights

1. Host Machine Resolves Container Names Directly

By intercepting domain names that end with a custom suffix (e.g., .docker) and forwarding them to Docker’s built-in DNS server, the host can access containers seamlessly.

Example:

curl http://myapp.docker:8080

The default suffix can be modified via command-line arguments or environment variables.

2. Lightweight Forwarding Logic

  • Domains matching .docker → Forwarded to Docker’s built-in DNS (127.0.0.11) for container IP resolution.
  • All other domains → Return REFUSED, so the host automatically uses public DNS (no impact on normal internet access).

The default forwarding address can be modified via command-line arguments or environment variables.

3. Gateway Access Support

A default domain gateway.docker is provided, which automatically resolves to the host machine’s IP.

The default gateway name can be modified via command-line arguments or environment variables.

4. Low Resource Footprint

Built on the ldns library and UDP protocol, it runs with minimal CPU and memory usage.

5. Usage Inside Containers

Docker’s built-in DNS forwards non-container-name domains to the host’s DNS service. This means you can also use domains like gateway.docker inside Docker containers:
Docker forwards the request to the host’s configured DNS server (i.e., this forwarder). The forwarder strips the .docker suffix to form a valid container name, then uses Docker’s built-in DNS to resolve the IP and return the result.

⚠️ Important Notes

  • Docker’s default bridge network (docker0) does not support inter-container access via container names (only via IP).

    Use a custom network (created with docker network create) to enable normal container name resolution.
    For details on Docker custom networks, refer to the official Docker documentation.

  • Domain name queries are case-insensitive.

🛠️ Working Principle

graph TD
    A[Host Initiates DNS Query] --> B{Does the domain end with .docker?}
    B -->|Yes| C[Strip .docker suffix → Forward to 127.0.0.11]
    C --> D[Return Container IP to Host]
    B -->|No| E[Return REFUSED]
    E --> F[Host Attempts Public DNS Resolution]
Loading

🚀 Deployment Methods

Solution Base Image Core Features Image Size Build Script
static scratch (empty) Contains only static binaries (no redundant system components) Binary < 1.5MB build-static.sh
alpine alpine:3.22 Lightweight Linux distro + runtime libraries + binaries Binary ≈ 40kB + Image ≈ 9MB build-alpine.sh

Method 1: Script Automation

  1. Download or clone the repository.
  2. Run the build script: build-alpine.sh or build-static.sh.
  3. Run the startup script docker-run.sh and follow the prompts to complete initialization and deployment.

Method 2: Manual Deployment

  1. Build the image and run the container:

    # Clone the source code
    git clone https://github.com/bytesharky/docker-dns
    # Domestic mirror (China):
    # git clone https://gitee.com/bytesharky/docker-dns
    
    cd docker-dns
    docker build -t docker-dns:static .
    
    # Start the container
    # Mount timezone data (optional: for local time in logs)
    # Set log level (optional: default is INFO)
    docker run -d \
      -e LOG_LEVEL=INFO \
      -e TZ=/zoneinfo/Asia/Shanghai \
      -v /usr/share/zoneinfo:/zoneinfo:ro \
      --network docker-net \
      --name docker-dns-a \
      -p 53:53/udp \
      --restart always \
      docker-dns:static
  2. Configure Host DNS
    Edit /etc/resolv.conf and set 127.0.0.1 as the top DNS server:

    nameserver 127.0.0.1       # Local forwarder
    nameserver 223.5.5.5       # Public DNS 1
    nameserver 8.8.8.8         # Public DNS 2
    

    (Optional) Prevent the file from being overwritten by the system:

    sudo chattr +i /etc/resolv.conf

Method 3: Use a Prebuilt Image

  1. Pull the prebuilt image:

    docker pull ccr.ccs.tencentyun.com/sharky/docker-dns:static
    
    docker tag ccr.ccs.tencentyun.com/sharky/docker-dns:static docker-dns:static
    
    # Start the container
    # Mount timezone data (optional: for local time in logs)
    # Set log level (optional: default is INFO)
    docker run -d \
      -e LOG_LEVEL=INFO \
      -e TZ=/zoneinfo/Asia/Shanghai \
      -v /usr/share/zoneinfo:/zoneinfo:ro \
      --network docker-net \
      --name docker-dns \
      -p 53:53/udp \
      --restart always \
      docker-dns:static
  2. Configure Host DNS
    Refer to Step 2 in Method 2.

✅ Function Verification

1. Verify Container Name Resolution

ping -c 3 docker-dns.docker

Expected output (IP = container’s internal network address):

PING docker-dns.docker (172.18.0.6): 56 data bytes
64 bytes from 172.18.0.6: icmp_seq=1 ttl=64 time=0.05 ms

2. Verify Public Domain Resolution

ping -c 3 github.com

Expected output (public IP):

PING github.com (140.82.112.4): 56 data bytes
64 bytes from 140.82.112.4: icmp_seq=1 ttl=51 time=10.2 ms

Troubleshooting

Control the program’s output by setting the LOG_LEVEL environment variable (default: INFO).

Supported levels: DEBUG, INFO, WARN, ERROR, FATAL

Log Level (DEBUG/INFO/WARN/ERROR/FATAL) Explanation

Number Log Level Core Meaning Severity Level
0 DEBUG Debug level: Prints detailed runtime info for development/testing (aids in code debugging) Lowest (only for dev environments)
1 INFO Info level: Records key statuses of normal system operation Low (safe for production; logs normal events)
2 WARN Warning level: Records non-fatal exceptions or potential risks (system continues running) Medium (monitor; may predict future issues)
3 ERROR Error level: Records fatal exceptions (single DNS resolution fails, but system remains functional) High (investigate promptly to avoid scope expansion)
4 FATAL Fatal level: Records critical errors that render the system completely inoperable Highest (system unavailable; urgent fix required)

📌 Summary

The Docker DNS Forwarder acts as a "bridge" between the host machine and Docker’s built-in DNS. Its key advantages:

  • 🟢 Host resolves .docker domains seamlessly
  • 🟢 No impact on normal internet DNS resolution
  • 🟢 Simple deployment + minimal resource usage

Ideal Use Cases

Development/testing environments, or scenarios where the host needs direct access to containers via container names.

Use with caution in production environments — fixed IP addresses are recommended instead.

Appendix: Command-Line Arguments / Environment Variables

Short Opt Long Option Env Variable Description Default Value
-L --log-level LOG_LEVEL Sets log verbosity (controls detail of output) INFO
-G --gateway GATEWAY_NAME Sets gateway name (inside Docker, the gateway is the host; allows resolving the host IP via gateway-name.suffix) gateway
-S --suffix SUFFIX_DOMAIN Sets the domain suffix for forwarded DNS queries .docker
-C --container CONTAINER_NAME Sets container name (used to send a test container-name.suffix resolution request to the forwarder on startup) docker-dns
-D --dns-server FORWARD_DNS Sets the target DNS server for forwarded queries (default: Docker’s built-in DNS) 127.0.0.11
-P --port LISTEN_PORT Sets the port the service listens on 53
-K --keep-suffix KEEP_SUFFIX Controls whether to retain the suffix when forwarding DNS queries (strip suffix when forwarding to 127.0.0.11) Disabled
-M --max-hops MAX_HOPS Sets maximum hop count for DNS queries (prevents looped queries) 3
-W --workers NUM_WORKERS Sets the number of worker threads for the service 4
-f --foreground - Runs the service in foreground mode (does not daemonize) Disabled (daemon by default)
-h --help - Shows this help message (lists options + descriptions) and exits -
root@VM-4-2-debian:~# ./docker-dns/docker-dns -h
Usage: ./docker-dns [OPTIONS]
Options:
  -L, --log-level    Set log level (DEBUG, default: INFO, WARN, ERROR, FATAL)
  -G, --gateway      Set gateway name (default: gateway)
  -S, --suffix       Set suffix name (default: .docker)
  -C, --container    Set container name (default: docker-dns)
  -D, --dns-server   Set forward DNS server (default: 127.0.0.11)
  -P, --port         Set listening port (default: 53)
  -K, --keep-suffix  keep suffix forward dns query (default: strip)
  -M, --max-hops     Set maximum hop count (default: 3)
  -W, --workers      Set number of worker threads (default: 4)
  -f, --foreground   Run in foreground mode (do not daemonize)
  -h, --help         Show this help message and exit

Environment variable:
  Command-line arguments take precedence over environment variables.
  --log-level    =>  LOG_LEVEL
  --gateway      =>  GATEWAY_NAME
  --suffix       =>  SUFFIX_DOMAIN
  --container    =>  CONTAINER_NAME
  --dns-server   =>  FORWARD_DNS
  --port         =>  LISTEN_PORT
  --keep-suffix  =>  KEEP_SUFFIX
  --max-hops     =>  MAX_HOPS
  --workers      =>  NUM_WORKERS

About

Docker DNS Forwarder is a lightweight tool that enables the host machine to resolve Docker container names to their IPs via domains in the format "container-name.custom-suffix" (e.g., ".docker")

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published