✦ For everyone, free.

Practical knowledge for real and everyday life

Home

4.2.6.4 CMD Shell Form

A focused guide to CMD Shell Form, connecting core concepts with practical Docker and container operations.

The CMD shell form writes the default command as a plain string, which Docker executes by wrapping it in a shell (/bin/sh -c on Linux), enabling shell features like variable expansion and command chaining at the cost of correct signal handling for the actual application process.

Syntax of the Shell Form

The shell form is written as ordinary text, exactly as it would be typed at a shell prompt.

CMD python app.py --port $PORT

Docker executes this as /bin/sh -c "python app.py --port $PORT", with the shell responsible for expanding $PORT before the actual python command runs.

Why Shell Features Are Sometimes Genuinely Needed

Some startup commands genuinely benefit from shell features — expanding an environment variable, chaining multiple commands together — which the shell form supports naturally without needing to explicitly invoke a shell as part of an exec-form array.

CMD echo "Starting on port $PORT" && python app.py
The Signal Handling Tradeoff

Because the shell becomes the container's actual main process, with the specified command running as a child process of that shell, signals sent to the container (such as SIGTERM on docker stop) are received by the shell, not necessarily forwarded correctly to the actual application process underneath it.

docker stop myapp

Depending on the shell's signal-forwarding behavior, the application process might not receive this signal promptly, potentially delaying shutdown until a forceful kill is issued instead.

Working Around the Signal Handling Issue

Using exec within the shell command replaces the shell process with the application process entirely, restoring correct signal delivery while still benefiting from shell-form syntax.

CMD exec python app.py --port $PORT
Why Understanding the Shell Form's Tradeoffs Matters

Choosing between the shell form and the exec form is not purely stylistic — it has a real, observable effect on how gracefully a container shuts down, making it worth deliberately choosing the exec form (or shell form with exec) for application startup commands specifically, rather than defaulting to the plain shell form without considering this consequence.