Why does stopping an idle container take the full 10-second timeout?

0
6
Asked By MellowBirch42 On

Running `docker stop` on an apparently idle container can still take about ten seconds. For example, starting `alpine sleep 1000` and then stopping it consistently waits for Docker's default grace period before sending SIGKILL.

The important detail is that PID 1 inside a PID namespace is treated as that namespace's init process. Signals such as SIGTERM are only delivered to it from an ancestor namespace when it has installed a handler for that signal. A process like `sleep` normally has no SIGTERM handler, so the signal never reaches it while it is PID 1. Docker then waits for the grace period and finally sends SIGKILL, which is delivered forcibly.

You can check whether PID 1 has signal handlers with `/proc//status`. For SIGTERM, inspect whether bit `0x4000` is set in `SigCgt`:

`grep SigCgt /proc/$(docker inspect -f '{{.State.Pid}}' sleeper)/status`

There are two common remedies. Using `exec` in an entrypoint script replaces the shell with the application, allowing the application to receive the stop signal directly. Using `--init` places a small init process such as `tini` at PID 1; it catches signals and reaps child processes, which is useful when the entrypoint cannot be changed. The configured stop signal also matters: some images use signals other than SIGTERM, so `STOPSIGNAL` should be checked as well.

4 Answers

Answered By BlueCedar88 On

Also check the image's configured `STOPSIGNAL`. Docker does not always send SIGTERM: nginx commonly uses SIGQUIT, and PostgreSQL uses SIGINT for particular shutdown behavior. You can inspect it with `docker inspect -f '{{.Config.StopSignal}}' `. A shell that handles neither the configured signal nor SIGTERM will still consume the full grace period, and this delay affects container recreations and redeploys too.

MellowBirch42 -

Good point. The signal mask must be checked against the signal Docker actually sends, not automatically against SIGTERM. A container that takes ten seconds to stop can add that delay to every replacement or deployment, not just to manual `docker stop` commands.

Answered By QuietMaple7 On

The ten seconds is Docker's normal shutdown grace period, not a slow runtime. Docker sends the configured stop signal first and waits; if the container has not exited, it sends SIGKILL. With a simple program such as `sleep` acting as PID 1, SIGTERM may never be delivered because it has no handler for that signal in the PID namespace. `SigCgt` can reveal this before testing.

MellowBirch42 -

Exactly. Saying the process is merely ignoring SIGTERM is slightly misleading here—the kernel can discard the signal before the process sees it. An ordinary host-level `sleep` exits immediately on SIGTERM, while the same program as namespace PID 1 can wait out the entire grace period.

Answered By SensibleOtter5 On

`--init` is another option: it puts `tini` in front as PID 1, so the stop signal has a handler and child processes can be reaped. That makes a program like `sleep` exit quickly, but it does not make a real application's shutdown instantaneous—the application still gets however long it needs to clean up. Use `--init` when you cannot modify the image or entrypoint; use `exec` when you control the script.

Answered By CopperLynx19 On

If an entrypoint script launches the application, use `exec`, for example `exec nginx -g 'daemon off;'`. Without it, the shell can remain as PID 1 and the application never receives the stop signal. In testing, replacing the shell with nginx reduced shutdown from roughly ten seconds to a few hundred milliseconds.

MellowBirch42 -

The exact behavior depends on the shell and command. A shell may optimize a single simple command by replacing itself, while a multi-command script usually stays as PID 1. The useful test is whether PID 1 has a handler for the signal Docker actually sends, rather than assuming every shell form has the same behavior.

Related Questions

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.