Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get an upstart script to properly manage running a docker image?

Tags:

docker

upstart

I have a local docker-registry that I'd like to manage with upstart.

I have the following script (in /etc/init/docker-registry.conf):

description "docker registry" 
author "me" 
start on filesystem and started docker 
stop on runlevel [!2345] 
respawn 
script
    /usr/bin/docker.io run -a stdout --rm --name=docker-registry \
    -v /var/local/docker-registry:/var/local/docker-registry \
    -p 5000:5000 mysite:5000/docker-registry
end script

I can start my docker registry fine with:

sudo start docker-registry

Response: docker-registry start/running, process 8620

Check to confirm its running?

sudo status docker-registry

Response: docker-registry start/running, process 8620

Trying to stop it with:

sudo stop docker-registry

Response: docker-registry stop/waiting

However, it doesn't actually stop. The process is still alive, the container is running, and it's still functioning perfectly


It does stop perfectly with:

docker stop docker-registry

I've tried adding this to the upstart script:

post-stop script
    docker stop docker-registry
end script

But it just returns: stop: Job failed while stopping

like image 567
Gerrat Avatar asked Jun 01 '14 17:06

Gerrat


People also ask

How do I keep docker images running?

The simplest way to keep the container running is to pass a command that never ends. We can use never-ending commands in any of the following ways: ENTRYPOINT or CMD directive in the Dockerfile. Overriding ENTRYPOINT or CMD in the docker run command.

Can you have multiple CMD in Dockerfile?

There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect. If CMD is used to provide default arguments for the ENTRYPOINT instruction, both the CMD and ENTRYPOINT instructions should be specified with the JSON array format.

How do I run a command in Dockerfile?

A Dockerfile will only use the final CMD defined. The CMD can be overridden when starting a container with docker run $image $other_command . ENTRYPOINT is also closely related to CMD and can modify the way a container is started from an image.


2 Answers

This worked for me:

description "container foo"
author "me"
start on filesystem and started docker
stop on runlevel [!2345]
respawn
script
  /usr/bin/docker start -a foo
end script
pre-stop script
  /usr/bin/docker stop foo
end script

I'm assuming the official Docker docs only care about the automatic starting part. The actual PID output by upstart differs from the actual docker process PID, and I suspect this causes some mismatch when stopping:

sudo service foo-docker start
foo-docker start/running, process 30313

What is this process? It looks like it's how Docker launched the container:

ps -p 30386 -f
UID        PID  PPID  C STIME TTY          TIME CMD
root     30386     1  0 14:48 ?        00:00:00 /bin/sh -e -c /usr/bin/docker start -a foo  /bin/sh

The PID of the actual command running inside the container is a different one:

pidof foo
30400

And killing the docker PID, as I guess the service foo-docker stop does, does not kill the container (or the command running within it):

sudo kill 30386 # or sudo service foo-docker stop
#30400 is still running
like image 132
Thomas Ferris Nicolaisen Avatar answered Oct 10 '22 03:10

Thomas Ferris Nicolaisen


Try prefixing the docker run line with exec. This will cause the docker container to run within the context of the shell script rather then the shell forking it. As a result, the docker run binary will receive the signals and clean itself up.

For example I have the following:

description "Docker container for OpenVPN server"
start on filesystem and started docker
stop on runlevel [!2345]
respawn
script
  exec docker run --volumes-from ovpn-data --rm -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn
end script

And running start docker-openvpn and stop docker-openvpn works as expected (--rm is honored as well).

Tested on Docker version 1.4.0, build 4595d4f on Ubuntu 14.04.

If it doesn't work, consider updating to use the upstream docker apt repo:

   curl https://get.docker.io/gpg | sudo apt-key add -
   echo deb http://get.docker.io/ubuntu docker main | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt-get update && sudo apt-get install -y lxc-docker
like image 31
2bluesc Avatar answered Oct 10 '22 01:10

2bluesc