In Docker, two instructions often cause confusion, especially for beginners: RUN and CMD. While both execute commands, they serve very different purposes and are used at different stages of the Docker image and container lifecycle.
This article explains what each instruction does, when to use it, and common best practices.
1. The RUN Instruction
The RUN instruction is executed during the image build process. Each RUN command creates a new layer in the Docker image and is typically used to prepare the environment required by your application.
Common use cases for RUN:
- Installing system packages or dependencies
- Configuring the operating system
- Preparing application prerequisites
Example:
RUN apt-get update && apt-get install -y curl
In this example:
- The command runs when the image is built
- The
curlpackage becomes part of the image - The command is not executed again when the container starts
Best Practice:
Combine related commands into a singleRUNinstruction to reduce the number of image layers and keep the image size smaller.
2. The CMD Instruction
The CMD instruction defines the default command that runs when a container starts. Unlike RUN, it is not executed during the image build, but at runtime.
Common use cases for CMD:
- Starting the main application process
- Defining a default behavior for the container
Example (recommended form):
CMD ["npm", "start"]
When a container is started from this image:
- Docker automatically runs
npm start - The command can be overridden at runtime:
docker run image-name npm test
Different Forms of CMD
1. Exec Form (Recommended)
CMD ["npm", "start"]
Advantages:
- Does not rely on a shell
- Handles system signals correctly (important for graceful shutdowns)
- More predictable and production-friendly
2. Shell Form
CMD npm start
Characteristics:
- Runs through
/bin/sh -c - Supports shell features such as
&&,;, and environment variable expansion - Less ideal for production workloads due to weaker signal handling
Key Differences Between RUN and CMD
| Aspect | RUN | CMD |
|---|---|---|
| Execution time | Image build | Container runtime |
| Primary purpose | Prepare the image | Run the application |
| Number allowed | Multiple | One (last one takes effect) |
| Creates image layer | Yes | No |
| Can be overridden | No | Yes |
A Simple Analogy
-
RUNis like preparing ingredients and cooking in the kitchen (building the image). -
CMDis like serving the dish and eating it (running the container).
Both are important, but they belong to different stages of the process.
Best Practice Recommendations
- Use
RUNonly for build-time setup and dependencies - Use
CMDto start a single main process - Prefer the exec form of
CMDin production environments - Avoid using
CMDto install packages - Combine
CMDwithENTRYPOINTwhen you need flexible runtime arguments
By understanding the difference between RUN and CMD, you can write Dockerfiles that are cleaner, more efficient, and easier to maintain—while avoiding common containerization pitfalls.
Top comments (0)