docker / docker/buildx

Warn that shells don't propagate signals in CMD documentation

Open
#3,154 3 comments 6 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area/docs kind/docs
Dominant language
Go
Stars
4.5k
Forks
682
Avg merge
2d 14h
Merged PRs (30d)
29

Description

Description

The documentation for CMD says: "If you want shell processing then you must either use the shell form or execute a shell directly, for example: CMD [ "sh", "-c", "echo $HOME" ]."

While this is correct, I think it would be good to warn that starting an application as a child of a shell breaks signal passing.

This may for instance lead someone to use a CMD line like this:

CMD [ "sh", "-c", "java $JAVA_OPTS -jar app.jar" ]

Here an sh process will be started which evaluates the $JAVA_OPTS variable and starts java as a child process. The problem with this is that sh doesn't pass signals like SIGTERM to its children. So, when a container is stopped, the SIGTERM signal will be sent to the sh process, but the signal won't reach the java process, so the application will not get a chance to respond to this signal by doing a graceful shutdown and will just be killed suddenly when the container gets stopped.

The documentation for ENTRYPOINT does mention that sh -c does not pass signals and that the executable will not receive a SIGTERM signal from docker stop <container>. Further down this documentation says: "If you need to write a starter script for a single executable, you can ensure that the final executable receives the Unix signals by using exec and gosu commands".

The problematic example above can indeed be fixed by adding exec to the mix, because exec will replace the sh process with the java process, so it will be a top-level process with process ID 1:

CMD [ "sh", "-c", "exec java $JAVA_OPTS -jar app.jar" ]

I think it would be good to point this out in the documentation for CMD. I have already encountered a lot of Dockerfile files that get this wrong.

P.S. I know another solution for the example above is using the JAVA_TOOL_OPTIONS or JDK_JAVA_OPTIONS environment variable, which don't need to be explicitly passed to java, but are picked up automatically, but this is not generally applicable to any process of course.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked CMD documentation and compare its shell-form guidance with the linked ENTRYPOINT documentation. Add a warning that commands run through sh -c may not receive stop signals, and explain exec as the relevant remedy. Done means the CMD section clearly covers signal propagation without contradicting the existing ENTRYPOINT guidance.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, dockerfile, shell
Domain
documentation
Issue type
Documentation
Difficulty
1/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
54/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.