DEV Community

Victor Amit
Victor Amit

Posted on

25

How to Set Up a Local DNS Server with Docker

A Detailed Guide on Setting Up a Local DNS Server Using Docker<br>

Setting up a local DNS server can greatly improve network management and streamline web development. By utilizing Docker, you can deploy a DNS server efficiently in a containerized environment. This guide will walk you through the process of setting up a local DNS server using Docker, from installation to advanced configurations.

What is DNS and Why Use Docker?

Domain Name System (DNS): DNS translates user-friendly domain names (like www.example.com) into IP addresses that computers use to communicate. A reliable DNS setup is crucial for seamless network operations and development.

Docker: Docker simplifies the deployment of applications by encapsulating them into containers. This approach ensures that your DNS server operates consistently across different environments.

Step 1: Install Docker

To get started, you need to install Docker on your operating system. Docker is available for Windows, macOS, and Linux. Visit the Docker website to download Docker Desktop. Follow the installation instructions for your OS, and verify the installation by running:



docker --version


Enter fullscreen mode Exit fullscreen mode

This command confirms that Docker is installed correctly.

Step 2: Choose DNS Server Software

For Docker-based DNS servers, consider the following options:

  • BIND9: Highly flexible and powerful, suitable for complex DNS setups.
  • dnsmasq: Lightweight and straightforward, ideal for small to medium-sized networks and local development.
  • CoreDNS: Modern and extensible, often used with Kubernetes for service discovery.

In this guide, we will use dnsmasq for its simplicity and effectiveness in local environments.

Step 3: Pull the dnsmasq Docker Image

Next, download the dnsmasq Docker image. Open your terminal and run:



docker pull andyshinn/dnsmasq


Enter fullscreen mode Exit fullscreen mode

This command pulls the dnsmasq image from Docker Hub. Ensure a stable internet connection for a successful download.

Step 4: Configure dnsmasq

Create a dnsmasq.conf file to define your DNS settings. Save this configuration file in an accessible location. Here’s a sample configuration:



# Log DNS queries
log-queries
# Listen on all network interfaces
listen-address=0.0.0.0
# Define domain records
address=/example.local/192.168.1.10
address=/anotherdomain.local/192.168.1.11
# Configure DNS caching
cache-size=1000
# Set DNS forwarders
server=8.8.8.8
server=8.8.4.4


Enter fullscreen mode Exit fullscreen mode

Configuration Details:

  • log-queries: Logs all DNS queries for monitoring purposes.
  • listen-address=0.0.0.0: Allows dnsmasq to listen on all network interfaces.
  • address=/example.local/192.168.1.10: Maps example.local to a specific IP address.
  • cache-size=1000: Defines the size of the DNS cache.
  • server=8.8.8.8 and server=8.8.4.4: Configures external DNS servers for fallback.

Step 5: Run the dnsmasq Container

Launch the dnsmasq container using your configuration file. Replace /path/to/your/dnsmasq.conf with the path to your file:



docker run --name mydns -d -p 53:53/udp -p 53:53 -v /path/to/your/dnsmasq.conf:/etc/dnsmasq.conf --cap-add=NET_ADMIN andyshinn/dnsmasq


Enter fullscreen mode Exit fullscreen mode

Command Breakdown:

  • --name mydns: Names the container "mydns".
  • -d: Runs the container in detached mode.
  • -p 53:53/udp -p 53:53: Maps DNS ports from the container to the host.
  • -v /path/to/your/dnsmasq.conf:/etc/dnsmasq.conf: Mounts your configuration file into the container.
  • --cap-add=NET_ADMIN: Provides necessary network permissions.
  • andyshinn/dnsmasq: Specifies the Docker image.

Step 6: Test Your DNS Server

Verify your DNS server’s functionality with dig or nslookup. Run these commands from another network machine:



dig @your_server_ip example.local


Enter fullscreen mode Exit fullscreen mode

or



nslookup example.local your_server_ip


Enter fullscreen mode Exit fullscreen mode

You should see a response with the IP address specified in your dnsmasq.conf.

Step 7: Configure Client Machines

Update the DNS settings on your client machines to use the Docker host’s IP address. This process varies by operating system but generally involves adjusting network adapter settings to point to the Docker host as the DNS server.

Step 8: Advanced Configuration and Security

DNSSEC: Implement DNS Security Extensions (DNSSEC) to enhance security and prevent DNS spoofing.

Rate Limiting: Apply rate limiting to safeguard against DNS amplification attacks and excessive queries.

Monitoring and Logging: Utilize monitoring tools to track DNS performance and review logs for any anomalies.

Backup and Recovery: Regularly back up your DNS configuration and establish a recovery plan to ensure continuity in case of failure.

Setting up a local DNS server using Docker provides an efficient and scalable solution for managing domain name resolution within your development environment. By following this guide—installing Docker, selecting and configuring DNS software, running the container, and implementing advanced security measures—you can establish a robust DNS server that enhances network management and development workflows.

For further information and support, explore Docker’s official documentation and the dnsmasq documentation.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (3)

Collapse
 
franco_defabrizio_94bca1 profile image
Franco De Fabrizio

I'm trying to set-up a combination of pihole (filtering blacklisted domains as malware, adult,...) and stubby (for DOT and DNSSEC) as two different container but i'm facing match issues when i want to implement ipv6 as well. The problem is if i don't implement ipv6 i can't prevent all the ipv6 clients from my local network to bypass the pihole/stubby tandem. If I would like to implement ipv6 as well I'm confronted with match problems as my ISP changes often my ipv6 address. How to implement a dynamic configuration within the pihole/stubby container with dyn dns as the used images are not my own but the pihole offical and Matthew Vances stubby image.

Collapse
 
victoramit profile image
Victor Amit

Setting up Pi-hole and Stubby as separate containers with IPv6 support while dealing with dynamic IPv6 addresses from your ISP can be challenging. Here's a detailed guide to address your situation:

Problem Overview

IPv6 bypass: Devices on your network may bypass Pi-hole if IPv6 is not properly configured.

Dynamic IPv6 addresses: ISPs often assign dynamic IPv6 prefixes, making static configurations unreliable.

Official images: Since you're using the official Pi-hole and Stubby images, customizing them is limited.

Solution

  1. Enable IPv6 on Pi-hole and Stubby

Ensure both containers support IPv6 by enabling it in their respective configurations:

Pi-hole:
Update docker-compose.yml or the docker run command to include IPv6.

networks:
pihole_network:
enable_ipv6: true

Add IPv6 configuration in Pi-hole’s settings (/etc/pihole/setupVars.conf).

Stubby:
Configure Stubby to use IPv6 DNS upstream servers, e.g., Cloudflare, Quad9, or Google DNS with DoT. Update stubby.yml as follows:

upstream_recursive_servers:

  • address_data: 2606:4700:4700::1111 tls_auth_name: "cloudflare-dns.com"
  • address_data: 2620:fe::fe tls_auth_name: "dns.quad9.net"
  1. Handle Dynamic IPv6 Addresses

Your ISP’s dynamic prefix requires dynamic updates to your Pi-hole and Stubby configurations. Use Dynamic DNS (DDNS) services like DuckDNS or No-IP to manage the changing IPv6 addresses.

Steps:

  1. Set up a DDNS client on your router or a device on your network:
    Configure your router or another device to update a DDNS hostname with your current IPv6 prefix.

  2. Use the DDNS hostname in your configurations:

In Pi-hole, update your dnsmasq configuration to forward queries to the Stubby container using the DDNS hostname instead of a static IPv6 address.

Ensure Stubby uses the DDNS hostname to resolve the upstream DNS servers dynamically.

  1. Automate IPv6 updates in the containers:

Use a script inside the Pi-hole container to monitor changes to the IPv6 prefix and update configurations dynamically.

Example script (place this in a crontab):

!/bin/bash

IPV6_PREFIX=$(dig +short your-ddns-hostname AAAA | sed -n 's/::.$//p')
if [[ -n "$IPV6_PREFIX" ]]; then
sed -i "s/^interface=::.
$/interface=${IPV6_PREFIX}::/" /etc/dnsmasq.d/02-custom.conf
pihole restartdns
fi

  1. Network Configuration

Configure your router to assign Pi-hole as the primary DNS for both IPv4 and IPv6 traffic.
Set the router's DNS server to Pi-hole’s IPv6 address or its DDNS hostname.Disable DNS functionality on the router to prevent bypassing.

  1. Testing the Setup

  2. Check IPv6 resolution:

dig AAAA example.com @

  1. Verify DNS queries are routed through Stubby:
    Check Stubby logs for DNS query traffic.

  2. Monitor and Adjust

Enable logging on Pi-hole to confirm IPv6 traffic filtering.
Periodically review DDNS updates and ensure the Pi-hole/Stubby tandem is functional.

Collapse
 
franco_defabrizio_94bca1 profile image
Franco De Fabrizio

Hi Victor,

Thank you for your response. Unfortunately, I’ve decided to give up on running these two Docker containers with IPv6, as I encountered numerous issues that I couldn’t resolve.

For instance, it was impossible to reach any public IPv6 address from inside the containers. Despite both the host and the containers being IPv6-capable, I consistently encountered the error message “Network unreachable, no route” when attempting to connect to public IPv6 DNS servers like Google or Cloudflare.

I explored multiple public discussions and forums for possible solutions, but after four weeks of troubleshooting, I ultimately decided to remove Docker entirely. It appears to me that IPv6 support in Docker is still lacking or requires significant workarounds.

Best regards

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay