CMD Instruction Reference
Specify the default command to run when starting a container
Syntax
The CMD instruction provides defaults for an executing container. These defaults can include an executable, or they can omit the executable, in which case you must specify an ENTRYPOINT instruction.
The CMD instruction is used to specify the default command that will run when a container starts. This command can be overridden by specifying a command when the container is launched.
There can only be one CMD instruction in a Dockerfile. If you list more than one CMD, then only the last CMD will take effect.
Forms of the CMD Instruction
The CMD instruction can be used in three forms:
The command is run directly, without shell processing:
CMD ["executable", "param1", "param2"]
This is the preferred form for CMD instructions in production Dockerfiles. It's parsed as a JSON array, which means that you must use double-quotes (") around words, not single-quotes (').
When used in conjunction with ENTRYPOINT, the CMD parameters are added to the ENTRYPOINT parameters:
ENTRYPOINT ["executable"]
CMD ["param1", "param2"]
In this case, the container will run executable param1 param2.
The command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows:
CMD command param1 param2
The shell form allows for shell processing, including variable substitution, but it doesn't allow for easy overriding at runtime.
Description
The main purpose of a CMD is to provide defaults for an executing container. These defaults can include an executable, or they can omit the executable, in which case you must specify an ENTRYPOINT instruction.
Unlike RUN, which executes commands during image build, CMD executes commands when a container starts. This means that CMD instructions don't add layers to the image during the build process.
If CMD is used to provide default arguments for the ENTRYPOINT instruction, both the CMD and ENTRYPOINT instructions should be specified with the JSON array format.
The CMD instruction can be overridden by providing command-line arguments when starting the container. For example, if your Dockerfile has:
CMD ["echo", "Hello, World!"]
You can override it at runtime with:
docker run myimage echo "Something else"
In this case, "Something else" will be echoed instead of "Hello, World!".
If you want to ensure your command cannot be overridden, use ENTRYPOINT instead, or combine ENTRYPOINT with CMD.
Examples
Basic Usage (Exec Form)
Specifying the default command using the exec form:
FROM ubuntu:20.04
CMD ["echo", "Hello, Docker!"]
When a container is started without any command-line arguments, it will output "Hello, Docker!".
Shell Form
Using environment variables with the shell form:
FROM ubuntu:20.04
ENV NAME Docker
CMD echo "Hello, $NAME!"
This will output "Hello, Docker!" with environment variable substitution.
Web Server
Running a web server:
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/
CMD ["nginx", "-g", "daemon off;"]
This starts the Nginx web server in the foreground when the container starts.
With ENTRYPOINT
Using CMD to provide default arguments to ENTRYPOINT:
FROM ubuntu:20.04
ENTRYPOINT ["echo"]
CMD ["Hello, Docker!"]
The default command is "echo Hello, Docker!", but you can override the message at runtime.
Running a Script
Running a script as the default command:
FROM python:3.9-slim
WORKDIR /app
COPY script.py .
CMD ["python", "script.py"]
This runs the Python script when the container starts.
Interactive Shell
Setting the default command to an interactive shell:
FROM ubuntu:20.04
CMD ["/bin/bash"]
This starts an interactive bash shell when the container is run with -it flags.
Best Practices
- Use the exec form: Always use the exec form (JSON array format) for CMD instructions to avoid unexpected behavior with shell processing.
- Only one CMD: Include only one CMD instruction in your Dockerfile. If multiple CMD instructions are listed, only the last one takes effect.
- Consider ENTRYPOINT: If your container has a specific purpose (like running a specific application), consider using ENTRYPOINT instead of CMD, or combining them.
- Keep it simple: Make your CMD clear and focused on the main purpose of the container.
- Don't rely on user input: Don't design your container to require specific command-line arguments, as it makes it harder to use and automate.
- Use environment variables: For configuration that might change, use environment variables rather than baking values into the CMD instruction.
- Provide clear documentation: Document what the default CMD does and how it can be overridden.
- Remember it can be overridden: Keep in mind that CMD can be completely overridden by runtime arguments, so don't rely on it for critical functionality.
CMD vs ENTRYPOINT
Understanding the difference between CMD and ENTRYPOINT is crucial for proper Dockerfile design:
CMD | ENTRYPOINT |
---|---|
Provides default arguments for the container | Configures the container to run as an executable |
Can be completely overridden by runtime arguments | Runtime arguments are appended as parameters |
Commonly used for providing default commands | Commonly used for defining the main executable |
Multiple CMD instructions will overwrite each other | Multiple ENTRYPOINT instructions will overwrite each other |
When both CMD and ENTRYPOINT are specified, the CMD arguments are passed to the ENTRYPOINT as parameters. For example:
ENTRYPOINT ["nginx"]
CMD ["-g", "daemon off;"]
results in the command: nginx -g daemon off;
If you specify runtime arguments when starting the container, they override the CMD but not the ENTRYPOINT.
Notes and Limitations
- There can only be one CMD instruction in a Dockerfile. If more than one is listed, only the last one takes effect.
- The CMD instruction does not execute anything during build time, it only specifies the intended command for the image.
- When using the shell form, the specified command is executed as an argument to
/bin/sh -c
on Linux orcmd /S /C
on Windows. - In the exec form, the command is executed directly without shell processing, which means that normal shell processing does not happen. For example, environment variable substitution doesn't happen when using the exec form.
- The exec form is parsed as a JSON array, which means that you must use double-quotes (") around words, not single-quotes (').
- CMD can be completely overridden by runtime arguments, while ENTRYPOINT can only have its parameters overridden.