Build and deploy tinydns data files with Docker
An excercise in bundling a working environment for running a single command
I’m a huge fan of djbdns, a DNS server/resolver written by D.J. Bernstein,
author of qmail. Albeit a bit special to set up, it is simple yet powerful
enough to not offload my DNS needs to an external service provider: it basically consists
of a single data
textfile, easily readable by humans, which is transformed by a
tinydns-data
executable.
Current DNS deployment: not elegant, but it works
DNS changes don’t occur very often for me, but I have always been unhappy with my deployment strategy … if it deserves that name, anyway:
- SSH into DNS machine, cd into tinydns’s root directory
- Backup the current
data
file and edit it - Run
make
to build the binary data file and scp it to secondary + tertiary DNS
# Makefile on DNS machine
data.cdb: data
/usr/local/bin/tinydns-data
scp data* tinydns@other.host:/service/tinydns/root/
scp data* tinydns@another.host:/var/service/tinydns/root/
Improvements I wanted to make:
- Elimate the backup copies by having
data
under version control - Deploy from my *NIX workstation instead of SSH’ing into a prod system
The first part was trivial and is not covered here.
The second part entailed having a local copy of the tinydns-data
binary and that meant two problems: I installed the djbdns suite from source and applied some
(battle-hardened) community patches; I shall like to avoid unpleasant surprises by using a stock
tinydns-data
that creates different *.cdb files.
Secondly, I will deploy from both a Linux and a Mac workstation, potentially
FreeBSD as well, and I would like to spare me maintaining 2-3 different binaries in
SCM.
Looking for a portable env to run a single command in
I felt this was a good use case for Vagrant or Docker. Since spinning up a full VM to run a single command felt like overkill and I’ve never actively worked with Docker, I went with the latter.
I ended up with this Dockerfile to bundle the tinydns-data
executable that I copied
from my DNS machine:
# Dockerfile
FROM alpine:3.7
WORKDIR /app
COPY bin/tinydns-data-linux-x86_64 /usr/local/bin/tinydns-data
To create/prepare the image:
docker build -t tinydns-data-builder .
make
it so!
To tie it all together, I modified the remote Makefile to automate this sequence on my local workstation:
- Launch the container image
- Copy the local tinydns
data
file into the containter - Run
tinydns-data
within the Docker instance to create the data.cdb file - Copy said file back to the Docker host
- Stop and remove the container
The resulting Makefile:
container_workdir := /app
deployables := data data.cdb
all: deploy
data.cdb: data
@echo -n "Building data.cdb in Docker container … "
$(eval TINYDNS_CONTAINER_ID=$(shell docker run -it -d tinydns-data-builder /bin/sh))
@docker cp ./data $(TINYDNS_CONTAINER_ID):$(container_workdir)
@docker exec -it $(TINYDNS_CONTAINER_ID) tinydns-data
@docker cp $(TINYDNS_CONTAINER_ID):$(container_workdir)/data.cdb .
@docker stop -t 0 $(TINYDNS_CONTAINER_ID) >/dev/null
@docker rm $(TINYDNS_CONTAINER_ID) >/dev/null
@echo ✅ Done
deploy: data.cdb
scp $(deployables) tinydns@primary.dns.host:/service/tinydns/tinydns/
scp $(deployables) tinydns@secondary.dns.host:/var/service/tinydns/tinydns/
scp $(deployables) tinydns@tertiary.dns.host:/etc/tinydns-ipv6/tinydns/
It could do with a make target to check a REVISION
file (e.g. generated after each deployment) if scp’ing
the data files is required, but why bother when copying over the unchanged files only takes 2-3 seconds.
I’m happy with this setup now. Also, can’t wait to play around with FreeBSD on Docker.
comments powered by Disqus