Docker and daemontools: best buddies

I've been running docker for quite a while now, as I found it fun to use, and rather easy to deploy even on a Slackware system. It is even better to use it with daemontools, both to supervise the docker process as well as to be an alternative to init inside containers. Here are some notes regarding this kind of usage:

Docker service under daemontools

Docker has a simple server mode called using docker -d, which simply listens to a local socket (typically /var/run/docker.sock) and emits logs to STDOUT. This mode is naturally suitable for running docker under daemontools as a supervise service, so much so that it is almost a no-brainer to configure:

$ cat /service/docker/run
#!/bin/sh
exec 2>&1
exec docker -d

Notice that the docker output is redirected, which can then be collected in a logger subprocess like multilog:

$ cat /service/docker/log/run
#!/bin/sh
exec multilog t ./main

daemontools in Docker containers

Docker containers can be thought of as lightweight virtual machines; some even view it as a better chroot environment with its own networking and namespaces separate from the host system. Thus, one can run init like supervisor services inside these containers, and daemontools is a good choice for such a supervisor:

# docker run -i -t ubuntu /bin/bash
# sed -e 's/main$/main universe' /etc/apt/sources.list > /etc/apt/sources.list.new
# mv /etc/apt/sources.list{.new,}
# apt-get update
# apt-get install daemontools-run
# sh -c 'exec /usr/bin/svscanboot &'
# ps axf
... add daemons, scripts and install them in /etc/service
# exit

Once you've created an image, you can use docker commit with the -run option to add a Cmd that will be run be default when creating container with docker run -d:

# $myservice_id=`docker ps -l -q`
# docker commit -run '{"Cmd": ["/usr/bin/svscanboot"]}' $myservice_id myservice

If you have services listening on ports, be sure to add a PortSpecs key in your docker commit -run invocation with the appropriate ports to be exposed on the container, like this:

# docker commit -run '{"Cmd": ["/usr/bin/svscanboot"], "PortSpecs": ["22", "80"]}' $myservice_id my_ssh_web_container

Once created, you can now run your container with docker run -d:

# docker run -d my_ssh_web_container
# docker inspect `docker ps -l -q` | grep IPAddress
... ssh or browse the IP address found above...