Best way to manage docker containers with supervisord

You can have Docker just not detach and then things work fine. We manage our Docker containers in this way through supervisor. Docker compose is great, but if you're already using Supervisor to manage non-docker things as well, it's nice to keep using it to have all your management in one place. We'll wrap our docker run in a bash script like the following and have supervisor track that, and everything works fine:

#!/bin/bash¬
TO_STOP=docker ps | grep $SERVICE_NAME | awk '{ print $1 }'¬
if [$TO_STOP != '']; then¬
    docker stop $SERVICE_NAME¬
fi¬
TO_REMOVE=docker ps -a | grep $SERVICE_NAME | awk '{ print $1 }'¬
if [$TO_REMOVE != '']; then¬
    docker rm $SERVICE_NAME¬
fi¬
¬
docker run -a stdout -a stderr --name="$SERVICE_NAME" \
 --rm $DOCKER_IMAGE:$DOCKER_TAG

Supervisor requires that the processes it manages do not daemonize, as per its documentation:

Programs meant to be run under supervisor should not daemonize themselves. Instead, they should run in the foreground. They should not detach from the terminal from which they are started.

This is largely incompatible with Docker, where the containers are subprocesses of the Docker process itself (i.e. and hence are not subprocesses of Supervisor).

To be able to use Docker with Supervisor, you could write an equivalent of the pidproxy program that works with Docker.


But really, the two tools aren't really architected to work together, so you should consider changing one or the other:

  • Consider replacing Supervisor with Docker Compose (which is designed to work with Docker)
  • Consider replacing Docker with Rocket (which doesn't have a "master" process)

You need to make sure you use stopsignal=INT in your supervisor config, then exec docker run normally.

[program:foo]
stopsignal=INT
command=docker -rm run whatever

At least this seems to work for me with docker version 1.9.1.

If you run docker from inside a shell script, it is very important that you have exec in front of the docker run command, so that docker run replaces the shell process and thus receives the SIGINT directly from supervisord.