What's the difference between stopping and killing a container?

5 minintermediatedocker-stopdocker-killgraceful-shutdown

Quick Answer

docker stop sends SIGTERM first, giving the container's main process a grace period (10 seconds by default) to shut down cleanly on its own, and only sends SIGKILL if it hasn't exited by the end of that grace period. docker kill sends SIGKILL (or another specified signal) immediately, with no grace period at all, forcibly terminating the process right away. stop is the correct default for anything that should be given a chance to clean up (closing database connections, finishing in-flight requests); kill is for situations where you need the container gone immediately and don't care about a graceful shutdown.

Detailed Answer

docker stop — graceful, with a timeout

docker stop my-container
  1. Sends SIGTERM to the container's main process (PID 1 inside its namespace).
  2. Waits up to a grace period (10 seconds by default) for the process to exit on its own.
  3. If it hasn't exited by the end of that grace period, Docker escalates and sends SIGKILL, forcibly terminating it immediately, with no further waiting.
docker stop -t 30 my-container    # give it up to 30 seconds before force-killing

The -t/--time flag adjusts this grace period. It is worth increasing for applications that need more time to finish in-flight work cleanly (draining active connections, completing a batch operation) before shutting down.

docker kill — immediate, no grace period

docker kill my-container            # sends SIGKILL immediately, by default
docker kill -s SIGINT my-container    # or, send a different specific signal instead

There is no grace period at all. The specified signal (SIGKILL by default) is sent right away. If that signal is SIGKILL specifically, the process cannot catch or ignore it, since SIGKILL is not interceptable by design in the Linux kernel. The process is terminated immediately and unconditionally.

Why the SIGTERM grace period matters

// A well-behaved application handles SIGTERM to shut down cleanly
process.on('SIGTERM', () => {
  console.log('Received SIGTERM, finishing in-flight requests...');
  server.close(() => {
    db.disconnect();
    process.exit(0);
  });
});

A well-designed application listens for SIGTERM and uses that grace period to stop accepting new requests, finish any requests already in progress, close database connections cleanly, and flush any buffered writes. None of this can happen if the process is killed outright with SIGKILL before it gets the chance. This is precisely why docker stop (not docker kill) is the correct default for routine container shutdowns, restarts, and deployments. Abruptly SIGKILLing a container mid-request can corrupt in-progress writes, leave connections in a bad state, or simply drop requests that were nearly complete.

The exec-form vs. shell-form connection

Recall from the Dockerfile topic that using shell form for CMD/ENTRYPOINT (CMD node server.js instead of CMD ["node", "server.js"]) makes a shell process PID 1 instead of the application itself. That shell often doesn't correctly forward SIGTERM to the actual application process underneath it. This is exactly why a container can appear to "ignore" docker stop and always take the full grace period before being force-killed. The SIGTERM sent by docker stop may never actually be reaching the application, even though the application itself would have handled it correctly if it had received it directly as PID 1.

When docker kill is the right choice

  • A container that's hung or unresponsive and clearly isn't going to shut down gracefully no matter how long you wait, and you need it gone immediately.
  • Local development/testing scenarios where a fast iteration loop matters more than clean shutdown semantics.
  • Debugging scenarios where you specifically want to simulate an abrupt, ungraceful termination (testing how a dependent system reacts to a sudden connection drop, for instance).

If you find yourself reaching for docker kill regularly just because docker stop "never works fast enough," that's usually a sign the container's CMD/ENTRYPOINT isn't actually receiving and handling SIGTERM correctly. It is not a reason to make kill the new default.

Related Resources