Skip to content

Warn that shells don't propagate signals in CMD documentation  #3154

Description

@breun

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions