Sending signals to a Docker container

We all know Docker, right? Running processes in Docker containers is nice and we can easily stop, start or restart the container with simple commands. However, you probably don’t want to “fully restart” a container all the time so sending signals to a Docker container becomes important.

 A customer application

We’re running several applications for our customers in a Docker environment. We use Docker because it’s straight-forward to spin-up new applications, especially with a Docker reverse proxy and an SSL wildcard certificate in place. Most of the applications are Python– and Django-based and it’s quite easy to run them via gunicorn. However, you need to restart or reload your Python process (i.e. gunicorn) in order to reload the configuration file or any other changes on the source code.

Restarting vs. reloading

Of course we could easily restart our Docker container by using docker restart <container>. Unfortunately, when we restart the container we’ll produce a downtime. In our case the restart of the containers takes about 30 seconds, since we run database migrations and compress static files in advance for a performance boost. So it doesn’t make any sense to restart the whole application just for a simple config or source code change. Instead of restarting a container we only want to reload the process. Fortunately, gunicorn accepts a SIGHUP for reload.

Sending signals

Sending a signal like SIGHUP to a Linux process is quite easy. We can use kill  or killall to send a signal to a process, but with Docker it gets a bit more tricky. Of course there are many ways to send signals to a Docker container. Here are some of

Option 1: Finding the PID of the container process

Since processes running inside a Docker container are also visible on the Docker host level, we can still use our well-known tools on the Docker host to send signals to the container processes. However, we need to find the right PID with:

docker inspect --format {{.State.Pid}} <container>
kill -SIGHUP <PID>

Option 2: Executing kill inside the container

Instead of finding the PID we can also use docker exec to run kill (or killall) inside the Docker container:

docker exec <container> kill -SIGHUP 1

Because the Docker container is spawning your process (CMD or ENTRYPOINT) as init process with PID 1, you can always send the signal to PID 1 inside the container.

Option 3: Using docker kill

In my opinion, using the docker kill command is the most sexy way to send signals to a Docker container:

docker kill --signal=HUP <container>

CMD exec vs. shell form

Please pay attention to the CMD statement in your Dockerfile:

CMD ["/init.sh"] # exec form
CMD /init.sh     # shell form

Always use the exec form if you want Docker to forward signals to your (sub-)process. This is not only important for sending custom signals to a Docker container, it’s also important to properly stop (i.e. docker stop) a container.

16 Comments

  • Rich

    “docker exec sv hup servicename” seems just as sexy as ‘docker kill’ 🙂

    Assuming you’re running Phusion baseimage-docker… (the my_init script doesn’t support HUP right now but seems doable, but they are using runit so we can use that). (maybe someone will modify it, it’s only 300 lines of python)

    From Runit FAQ:
    I want to send a service daemon the HUP signal, to have it re-read its configuration, or I want to send it the INT signal. How can a send signals to a service daemon?
    Answer: Use the sv program. E.g., to send the dhcp service the HUP signal, do:

    # sv hup dhcp

    http://smarden.org/runit/faq.html#signal

    • Dominique Barton

      Hi Rich

      Thanks for your comment!

      Yeah sv is also working fine to send signals. However, you need to make sure that sv is installed in your container. Unfortunately, all of my images/containers haven’t installed sv, so I can’t use that one.

      Cheers
      Domi

  • Kunju

    Hi Domi,

    This article is very much helpful to use to know about signal on container, thanks very much.

    And,
    I think Mr.Rich could be mentioned sv as container name, it is not a tool, and since we can achieve to send a signal by using “docker exec hup dhcp”.

    Thanks,
    Kunju.

  • Kunju

    by using docker exec hup dhcp

  • Kunju

    docker exec containerid hup dhcp

  • Philipp Gassmann

    With docker-compose:
    docker-compose kill -s HUP

    Because I had a container in which the main process did not run with pid 1, the above didn’t do the right thing so I used:
    docker-compose exec -T backuppc pkill -SIGHUP BackupPC

    • Philipp Gassmann

      With docker-compose:
      docker-compose kill -s HUP containername

      Because I had a container in which the main process did not run with pid 1, the above didn’t do the right thing so I used:
      docker-compose exec -T containername pkill -SIGHUP processname

  • hair removal

    what is this? huhu cant understand

  • Salma Hayek measurements

    Do you know about Salma Hayek? She is an American actress. If you want to know more about Salma Hayek then go to this blog and read its article.

  • run 3

    Unfortunately! I really like this girl’s style but unfortunately there is no chance anymore, thank you for creating a better style.

  • pi

    Lent you have shared, good stuff.