How to Set Up a Local DNS Server Using Docker: A Practical Guide for Developers

DNS Server in Docker

🔍 Overview

Setting up a local DNS server may sound like something only large-scale IT teams need. But in reality, having your own DNS server locally can speed up development, enable custom domain routing, and improve testing environments—especially in microservice setups.

In this tutorial, you’ll learn how to deploy a lightweight DNS server locally using Docker—without getting tangled in complex configurations.

📌 Why Set Up a Local DNS Server?

Before diving into containers and configs, let’s understand the benefits of running a DNS server locally:

  • 🔁 Custom domain routing (e.g., myapp.local127.0.0.1)
  • 🧪 Isolated testing environments without altering /etc/hosts
  • Faster DNS resolution during development
  • 🧩 Service discovery in dev environments

And the best part? With Docker, it’s fully portable, clean, and easy to reset.

🛠️ Tools We’ll Use

We’ll use the following:

  • Docker (container platform)
  • Bind9 DNS server (in a container)
  • Optional: dig or nslookup for testing DNS queries

📁 Folder Structure

Start by creating a working directory:

$ mkdir docker-local-dns && cd docker-local-dns

Inside, create:

.
├── Dockerfile
├── named.conf
├── db.localhost
└── named.conf.options

🐳 Step 1: Create the Dockerfile

Let’s create a Dockerfile that sets up a Bind9 DNS server:

FROM ubuntu:22.04

RUN apt-get update && \
apt-get install -y bind9 dnsutils && \
mkdir -p /etc/bind/zones

COPY named.conf /etc/bind/named.conf
COPY named.conf.options /etc/bind/named.conf.options
COPY db.localhost /etc/bind/zones/db.localhost

EXPOSE 53/udp
EXPOSE 53/tcp

CMD ["named", "-f", "-u", "bind"]

⚙️ Step 2: Configuration Files

named.conf

include "/etc/bind/named.conf.options";

zone "mydomain.local" {
type master;
file "/etc/bind/zones/db.localhost";
};

named.conf.options

options {
directory "/var/cache/bind";

listen-on port 53 { any; };
allow-query { any; };
recursion yes;

forwarders {
8.8.8.8;
1.1.1.1;
};

dnssec-validation no;
};

db.localhost

$TTL    604800
@ IN SOA ns.mydomain.local. admin.mydomain.local. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS ns.mydomain.local.
ns IN A 127.0.0.1
app IN A 127.0.0.1

This sets app.mydomain.local and ns.mydomain.local to resolve to 127.0.0.1.

🧱 Step 3: Build and Run the Docker Container

Now let’s build and run the container:

docker build -t local-dns .
docker run -d --name dns-server \
-p 53:53/udp -p 53:53/tcp \
local-dns

🧪 Step 4: Test Your DNS Server

You can now test it using dig:

dig @127.0.0.1 app.mydomain.local

Expected result:

;; ANSWER SECTION:
app.mydomain.local. 604800 IN A 127.0.0.1

If you’re using Linux, you can temporarily set your system to use this DNS:

$ sudo systemd-resolve --set-dns=127.0.0.1 --interface=lo

Or for macOS, go to System Settings → Network → DNS, and add 127.0.0.1.

🎯 Bonus: Add More Records

Want to add more custom domains?

Just edit db.localhost like this:

backend IN A 127.0.0.1
frontend IN A 127.0.0.1

Then restart your container:

$ docker restart dns-server

🧼 Clean Up

To remove everything:

$ docker rm -f dns-server
$ docker rmi local-dns

🔐 Security Note

This setup is for local/dev use only. Do not expose it to public networks without proper hardening (ACLs, logging, access control).

📚 Conclusion

Using Docker to set up a local DNS server is a powerful and flexible way to manage domain names in your local development environment. It’s faster than editing /etc/hosts, more scalable, and great for working with microservices or container-based systems.

If you’re looking to supercharge your dev workflow—this is one of the best hidden gems to try.

(Visited 33 times, 2 visits today)

You may also like