Cloud Native 10 min read

How to Gracefully Shut Down Docker Containers Using Signals, ENTRYPOINT, and CMD

This article explains Linux signals, the difference between exec and shell forms of Dockerfile ENTRYPOINT and CMD, and demonstrates with Go and shell‑script examples how to configure containers so that docker stop sends SIGTERM and allows applications to exit cleanly.

Efficient Ops
Efficient Ops
Efficient Ops
How to Gracefully Shut Down Docker Containers Using Signals, ENTRYPOINT, and CMD

1 Signals

Signal is a notification mechanism for processes, sometimes called a software interrupt.

Linux defines standard signals numbered 1‑31, which can be listed with

kill -l

. Commonly used signals include:

SIGHUP

– sent when a terminal disconnects; often used to tell daemons to reload configuration.

SIGINT

– generated by Ctrl‑C ; default action terminates the process.

SIGQUIT

– generated by Ctrl‑\ ; terminates the process and produces a core dump.

SIGKILL

– uncatchable, unignorable kill signal that always terminates a process.

SIGTERM

– the default termination signal used by

kill

,

killall

and

pkill

; well‑behaved programs should handle it to clean up resources before exiting.

SIGTSTP

– sent by Ctrl‑Z to stop a foreground job.

Note that Ctrl‑D does not send a signal; it signals EOF on stdin.

2 ENTRYPOINT, CMD

Both instructions specify the program that runs when a container starts. Each has two syntaxes: exec form (recommended) and shell form.

Exec form runs the program directly, preserving the process ID and allowing signals to be delivered:

<code>CMD ["executable","param1","param2"]</code>

Shell form runs the command via

/bin/sh -c

, which creates an intermediate shell that does not forward signals to the actual program:

<code>CMD command param1 param2</code>

The same applies to

ENTRYPOINT

:

<code>ENTRYPOINT ["executable","param1","param2"]</code>
<code>ENTRYPOINT command param1 param2</code>

When a container is stopped with

docker stop

, Docker sends

SIGTERM

(and after a timeout,

SIGKILL

). If the program is started via the shell form, it never receives the signal, resulting in a forced termination.

3 Examples

3.1 Go signal handler

<code>package main

import (
    "fmt"
    "os"
    "os/signal"
    "syscall"
)

func main() {
    sigs := make(chan os.Signal, 1)
    done := make(chan bool, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        done <- true
    }()
    fmt.Println("awaiting signal")
    <-done
    fmt.Println("exiting")
}
</code>

Dockerfile using exec form:

<code>FROM busybox
COPY signals /signals
CMD ["/signals"]
</code>

Running the container and stopping it with

docker stop

yields a graceful shutdown (≈0.73 s) because the Go program receives

SIGTERM

and exits cleanly.

Changing

CMD

to the shell form (

CMD /signals

) prevents signal delivery;

docker stop

then waits the full timeout (≈10.7 s) before forcing termination with

SIGKILL

.

3.2 Shell script wrapper

If the container starts a shell script, the script must use

exec

to replace the shell with the actual program, otherwise signals are still lost.

<code># start.sh
#!/bin/sh
exec /signals   # forward signals
</code>

Dockerfile:

<code>FROM busybox
COPY signals /signals
COPY start.sh /start.sh
CMD ["/start.sh"]
</code>

With the

exec

added inside the script,

docker stop

again shuts down the container in under a second.

These examples demonstrate that using the exec form for

ENTRYPOINT

or

CMD

, and ensuring any wrapper scripts also use

exec

, are essential for graceful container shutdown.

DockercontainerGraceful ShutdownCMDSignalsENTRYPOINT
Efficient Ops
Written by

Efficient Ops

This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.