You are here

Docker - a DNS server container (bis)

logoObsolete - refer to this article.


After having tested a first Docker container for a bind server, I end up with the one described here.

Dockerfile

The Dockerfile contains following instructions:

FROM pascalbod/ubuntu:14.04.1-20141221

RUN apt-get update \
 && apt-get install -y bind9 dnsutils \
 && rm -rf /var/lib/apt/lists/*

ADD start /start
RUN chmod 755 /start

EXPOSE 53/udp

CMD ["/start"]

The image pascalbod/ubuntu is available on Docker Hub. The only difference (for now) with the existing official Ubuntu image is that it contains the nano editor.

The volume /data/bind must be provided by a data container (see below), containing bind9 configuration files. As those configuration files are static, they could be inserted into the bind server container, without linking this one with a data container. But I'll have to design some other containers handling dynamic data (a mail server for instance), and I'd like to use the same design pattern for all my containers...

Start file

The start command file contains following instructions:

#!/bin/bash

# Copy configuration files if not yet done.
if [ -e /opt/pascalbod/bindInitFlag ] ; then
  echo "Bind configuration already initialized"
else
  echo "Starting configuration..."
  # Ensure right ownership.
  chmod -R 775 /data/bind
  chown -R root:bind /data/bind
  cp /data/bind/etc/* /etc/bind/
  mkdir -p /opt/pascalbod
  touch /opt/pascalbod/bindInitFlag
  echo "Configuration done"
fi

echo "Starting named..."
mkdir -m 0775 -p /var/run/named
chown root:bind /var/run/named
touch /var/log/query.log
chown bind /var/log/query.log
exec /usr/sbin/named -u bind -f

The first time the container is started, configuration data is copied from data container. The file /opt/pascalbod/bindInitFlag is used as a flag, to record whether this copy operation has already been performed. Consequence: when configuration data is modified, the container must be rebuilt.

Data container

Data container is built using following Dockerfile:

FROM pascalbod/ubuntu:14.04.1-20141221

COPY zones/* /data/bind/etc/

VOLUME /data/bind

CMD ["true"]

The same Ubuntu image than for the bind server container is used. That's quite a large image, but as it is already used by the bind server, no disk space is wasted.

In the directory where this Dockerfile is, create the subdirectory zones, and put there all configuration files for bind server. Then, build the image and create the container:

docker build -t dnsserverdata .
docker run --name dnsserverdata dnsserverdata

You can get up-to-date Dockerfile and associated build instructions in this GitHub repository.

Running the bind server container

Build the bind server container, then create and run it:

docker build -t dnsserver:v1 .
docker run --name dnsserver --volumes-from dnsserverdata -d \
-p 53:53/udp -p 53:53 --restart=always dnsserver:v1

Up-to-date Dockerfile and start file are available from this Docker Hub repository.