Every container has a PID 1. It is the process that the OCI runtime
invokes via execve(2). If that process does not handle signals
correctly, the container cannot be stopped gracefully.
This is the root cause of “container takes 10 seconds to stop.” The
default --stop-timeout is 10 seconds. If PID 1 ignores SIGTERM,
docker stop waits the full timeout before sending SIGKILL.
The special semantics of PID 1
In Linux, when the kernel delivers a signal whose default action is
to terminate the process, PID 1 is exempt. PID 1 only acts on
signals that have an installed handler.
This is a feature for the system init process. The kernel assumes
that PID 1 knows what it is doing and only acts when PID 1 chooses
to. For container workloads, this feature becomes a footgun: most
workloads do not know that they are PID 1 and do not install
handlers.
sequenceDiagram participant D as docker stop participant K as Kernel participant PID1 as Container PID 1 participant App as Application D->>K: send SIGTERM to PID 1 alt PID 1 has a handler K->>PID1: deliver SIGTERM PID1->>App: forward or handle App-->>PID1: exit PID1-->>K: exit 0 else PID 1 has no handler (e.g. shell) K->>PID1: ignore (default for PID 1) Note over K: wait --stop-timeout D->>K: timeout reached D->>K: send SIGKILL to PID 1 K->>PID1: deliver SIGKILL PID1-->>K: killed (no cleanup) end
The single commonest cause: a shell-form CMD
Read-only / Safeis PID 1 a shell?— Compare the two. A container whose Path is /bin/sh with a -c argument cannot receive SIGTERM, no matter what the application does.
Service impact possiblemeasure it, do not guess— Time the stop. A duration that lands within a few milliseconds of --stop-timeout means the timeout expired and SIGKILL did the work; a fast stop means PID 1 handled the signal.
web
real 0m10.043s
user 0m0.019s
sys 0m0.011s
exit=137 oom=false
Illustrative output
The pair of numbers is the verification, and each one rules something
out on its own:
Duration at the timeout, exit 137.137 is 128 + 9: SIGKILL.
With oom=false, nothing ran out of memory — the stop timeout
expired. PID 1 ignored SIGTERM.
Fast stop, exit 143.143 is 128 + 15: SIGTERM. The signal
was delivered and acted on. This is the working case.
Fast stop, exit 0. PID 1 handled SIGTERM, ran its shutdown
path, and exited deliberately. This is the best case.
Diagnosing a container that takes 10 seconds to stop
Read-only / Safeinspect stop behavior— A container's PID 1 entrypoint determines whether SIGTERM is handled.
The container’s --stop-timeout should be at least as long as
the application’s graceful shutdown timeout, plus a buffer.
Anything shorter forces SIGKILL before the app has finished
draining.
Knowledge check
Knowledge check · 6 questions
Q1. PID 1 inside a container is special because:
Q2. A shell as PID 1 will receive SIGTERM and shut down cleanly.
Q3. Name the small init process designed to forward signals and reap zombies for containers.
Q4. A container always takes exactly 10 seconds to stop and exits 137, with State.OOMKilled false. docker inspect shows Path=/bin/sh and Args=["-c","python3 /app/server.py"]. What should you change?
Q5. Which of these result in the application process receiving SIGTERM directly as PID 1? Select all that apply.
Q6. Because the default STOPSIGNAL is SIGTERM, every official image shuts down gracefully on `docker stop` without further configuration.
Passing score: 75%. Answers are checked in this browser.