Docker Curriculum
On this page
- Entrypoint Vs Cmd
- What They Do
- CMD
- ENTRYPOINT
- How CMD and ENTRYPOINT Interact
- Shell Form vs Exec Form
- Exec Form (Recommended)
- Shell Form (Avoid for Entrypoints)
- The Complete Interaction Matrix
- The Correct Pattern for Application Containers
- The Wrapper Script Pattern (Production Best Practice)
- When to Use CMD Alone
- When to Use ENTRYPOINT Alone
- Overriding ENTRYPOINT at Runtime
- AWS ECS Context
- Summary
Entrypoint Vs Cmd
ENTRYPOINT and CMD are the two Dockerfile instructions that define what runs when a container starts. They are both commonly used, frequently confused, and their interaction is subtle. Getting this wrong means containers that cannot be overridden cleanly, that break when run with arguments, or that behave differently than the documentation says they should.
This file explains exactly what each instruction does, how they interact, and what the correct pattern is for each type of application.
What They Do
CMD
CMD sets the default command for the container. It is what runs when no command is specified in docker run. If a command is provided at runtime, CMD is completely replaced.
ENTRYPOINT
ENTRYPOINT sets the executable that always runs. It is not replaced by runtime arguments — the runtime arguments are appended to the entrypoint as additional arguments.
The entrypoint is always echo. The text after the image name becomes the argument.
How CMD and ENTRYPOINT Interact
When both are defined, CMD provides the default arguments for the ENTRYPOINT.
This is the most powerful pattern: ENTRYPOINT is the program, CMD is the default argument. Users can customize the behavior by providing different arguments without knowing or caring about the underlying executable.
Shell Form vs Exec Form
Both instructions support two forms, and the choice matters significantly.
Exec Form (Recommended)
The exec form runs the command directly — no shell wrapping. The process becomes PID 1 inside the container. This means it receives signals (like SIGTERM from docker stop) directly.
Shell Form (Avoid for Entrypoints)
The shell form wraps the command in /bin/sh -c. This creates a shell as PID 1, and the shell runs the actual command. When docker stop sends SIGTERM, it goes to the shell — not to your application. The shell may or may not forward it. This leads to containers that do not shut down gracefully and must be killed.
Rule: Always use exec form (["..."]) for ENTRYPOINT. Use exec form for CMD when paired with an ENTRYPOINT.
The Complete Interaction Matrix
The Correct Pattern for Application Containers
For a service that runs as a daemon (web server, API, worker), the standard pattern is:
Users can adjust Gunicorn arguments without knowing how the image was built.
The Wrapper Script Pattern (Production Best Practice)
Many production containers use a shell wrapper script as the ENTRYPOINT. This script performs initialization — setting up environment, running migrations, waiting for dependencies — before handing off to the main application.
The crucial last line of the script is exec "$@". This uses exec to replace the shell process with the CMD — making the CMD the new PID 1 and ensuring it receives signals correctly. Without exec, the shell stays as PID 1 and swallows signals.
This pattern is used by all official Docker Hub images (postgres, redis, nginx, etc.) — it is the production standard.
When to Use CMD Alone
Use CMD alone (no ENTRYPOINT) when:
- You want the container to be usable as a general-purpose shell environment
- You are building a base image for others to extend
- The container needs to be easily overridden with any command
When to Use ENTRYPOINT Alone
Use ENTRYPOINT alone when the container is a specific tool and should always run that tool:
Overriding ENTRYPOINT at Runtime
If you need to bypass the entrypoint entirely (useful for debugging):
AWS ECS Context
In ECS task definitions, command corresponds to CMD and entryPoint corresponds to ENTRYPOINT:
If you override command in the task definition, the entryPoint from the image still runs first — same behavior as docker run.
Summary
CMDsets the default command — completely replaced when arguments are provided at runtimeENTRYPOINTsets the executable — runtime arguments are appended, not replaced; use--entrypointto override it- When both are defined,
ENTRYPOINTis the executable andCMDprovides its default arguments — runtime args replace theCMDportion - Always use exec form (
["..."]) forENTRYPOINTto ensure your application is PID 1 and receives signals directly - The wrapper script pattern (
ENTRYPOINT ["docker-entrypoint.sh"]+CMD ["app"]) is the production standard — it enables initialization steps while preserving signal handling viaexec "$@" - Use
CMDalone for general-purpose base images; useENTRYPOINTalone for container-as-tool patterns
In the next file, we cover the ARG vs ENV distinction — two instructions that look similar but have fundamentally different scopes and security implications.