Running a DNS Server in Docker

foo0x29a
Nagoya Foundation
Published in
3 min readFeb 24, 2019

--

Disclaimer: The intent of this post is not to provide a production-ready setup. It was part of a hobbyist project, and I would like to share it as an idea that might be useful for some of you.

Docker is a container platform that has gained popularity over the last years. It is being heavily used to speed up the process of development and deployment, miming the production environment locally.

In a scenario of development of distributed systems, multiple applications may perform calls to each other (e.g. through RESTful APIs) in order to communicate. In most cases these calls would use localhost as domain name, since the host would be one’s own local machine.

The name resolution in the Linux environments is described in the /etc/nsswitch.conf file. By default, it has an entry with files dns, which means it will first check the /etc/hosts file, and then the DNS server.

The Domain Name System (DNS) is a service that translates domain names into IP addresses, and in this article there will be a short overview of how to run a DNS server in a Docker container.

Docker network

The first step would be creating a Docker network. It is also possible to use the default network created during the installation, but it wont’t be possible to assign a static IP address to your container. The following command creates an arbitrary network called nagoya-net with range 172.20.0.0/16 . It will allow us to run containers with static IPs.

$ sudo docker network create --subnet=172.20.0.0/16 nagoya-net

BIND9

There are many name servers available, but a popular choice is BIND9. It is an Open Source name server and simple to configure.

The first file to configure is the named.conf.options:

It describes basic configurations such as forwarders, interface to listen and cache directory. In this example, the Google DNS is used as a forwarder.

Next, the zone called nagoya-foundation.com is created, and it points to a file called /etc/bind/zones/db.nagoya-foundation.com. It is defined in the named.conf.local file:

Now a file called db.nagoya-foundation.com with all the hosts (e.g. services running in Docker containers) will be defined:

In the example, there are two hosts host1.nagoya-foundation.com and host2.nagoya-foundation.com, and one name server ns1.nagoya-foundation.com. Make the necessary changes to fit both your Docker network and domains.

The next step is the Docker image:

Save all the configuration files in the same directory, including the Dockerfile.

Running

First build the Docker image. In this example the name is bind9:

$ sudo docker build -t bind9 .

Run a container in background, using the same IP as in the db.nagoya-foundation.com file and the same Docker network created:

$ sudo docker run -d --rm --name=dns-server --net=nagoya-net --ip=172.20.0.2 bind9

Then enable the bind9 daemon:

$ sudo docker exec -d dns-server /etc/init.d/bind9 start

Now it is possible to run the two hosts using the dns-server container as a DNS server:

$ sudo docker run -d --rm --name=host1 --net=nagoya-net --ip=172.20.0.3 --dns=172.20.0.2 ubuntu:bionic /bin/bash -c "while :; do sleep 10; done"$ sudo docker run -d --rm --name=host2 --net=nagoya-net --ip=172.20.0.4 --dns=172.20.0.2 ubuntu:bionic /bin/bash -c "while :; do sleep 10; done"

Inside the container, it is possible to verify that the host2 is reachable from the host1, using the DNS:

$ sudo docker exec -it host1 bash

The output of the ping command is as follows:

root@4c4178369feb:/# ping host2.nagoya-foundation.com
PING host2.nagoya-foundation.com (172.20.0.4) 56(84) bytes of data.
64 bytes from host2.nagoya-net (172.20.0.4): icmp_seq=1 ttl=64 time=0.148 ms
64 bytes from host2.nagoya-net (172.20.0.4): icmp_seq=2 ttl=64 time=0.101 ms
64 bytes from host2.nagoya-net (172.20.0.4): icmp_seq=3 ttl=64 time=0.112 ms
^C
--- host2.nagoya-foundation.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2055ms
rtt min/avg/max/mdev = 0.101/0.120/0.148/0.022 ms
root@4c4178369feb:/#

--

--