Signals in Docker

Introduction

Docker containers are regular Linux processes. This means:

  • There are no Docker-specific signals.
  • Docker can send Linux signals to the containers.
  • Docker forwards signals to the process with PID 1 (the ENTRYPOINT process) inside the container.

Why is PID 1 important in a Docker container?

Inside a Docker container, the ENTRYPOINT process is the first process started in the container's PID namespace. That's why it has PID 1.

This is the process that will receive signals sent by Docker. If it doesn't handle signals properly, those signals might be ignored.

Stopping containers

What happens when you run docker stop?

This is the sequence of events triggered by docker stop:

  1. A SIGTERM signal is sent to the process with PID 1 inside the container (soft kill).
  2. Some time is given to the process to handle the signal (10 seconds by default, although this timeout can be configured).
  3. If the container is still running after the timeout expires, a SIGKILL signal is sent to the process with PID 1 inside the container (hard kill).

What happens when you run docker kill?

The SIGKILL signal is sent to the process with PID 1 inside the container when you run docker kill, so it is hard killed.

docker stop vs docker kill: what's the difference?

With docker stop, the process with PID 1 inside the container has some time to handle the SIGTERM signal and exit gracefully before being hard killed. It can close file descriptors, clean up temporary files, etc.

With docker kill, the process is hard killed immediately. It doesn't have time to handle the signal and exit gracefully.

How can I make my container shut down gracefully?

To implement graceful shutdown for a Docker container and avoid production outages, you need to follow these steps:

  • Handle the SIGTERM signal: your app needs to exit gracefully when it receives this signal.
  • Use the exec form for the ENTRYPOINT: the shell form starts the app as a subcommand of the shell, which does not forward signals.
  • Configure the docker stop timeout: if 10 seconds is not enough for your app to exit gracefully, you can increase it.
  • If your container runs multiple processes, you can use an init process to forward signals to them.

Sending signals to containers

How can I send a signal to a process inside a Docker container?

You can use docker kill to send a signal to the process with PID 1 inside the container:

docker kill --signal SIGUSR1 CONTAINER1

This example sends the SIGUSR1 signal to the container CONTAINER1.

Do you want to try this in a real-world scenario? Solve this free interactive Docker challenge from your browser.

What if the process does not have PID 1?

If the container has an init process, it will forward the signal to the other processes inside the container.

What if the container does not have an init process?

You can send signals inside the container using the docker exec command. First list the PIDs of the processes in the container:

docker exec CONTAINER1 ps

Then run docker exec again to send the signal:

docker exec CONTAINER1 kill -SIGUSR2 5

This example sends the SIGUSR2 signal to the process with PID 5 inside the container CONTAINER1.

What if the Docker image is minimal or distroless?

In that case, the Docker image won't have the ps or kill commands, so you can't send signals inside the container using those commands. However, you can send signals from the host to processes running inside the container as they are regular Linux processes.

First, find the PID of the process you want to send the signal to using the docker top command:

docker top CONTAINER1

The value of the PID column is the PID of the process on the host system, not the PID of the process inside the container. You can use that PID to send the signal using the kill command from the host system:

kill -SIGHUP 1234

This example sends the SIGHUP signal to the process with PID 1234 on the host system, which is a process running inside the container CONTAINER1.

Troubleshooting

Where can I practice troubleshooting in a real-world scenario?

You can apply what you've just learned in this free interactive scenario: Reloading without restarting the Docker container