When writing Dockerfiles, two instructions often confuse beginners: RUN and CMD. While they may look similar (both execute commands), they serve different purposes in the container lifecycle.
1️⃣ What is RUN?
- Purpose: Executes a command at build time.
- Effect: Creates a new image layer with the results of that command.
- Use Case: Installing dependencies, setting up environment, modifying the image.
📌 Example:
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y python3
Here, RUN installs Python during image build. The resulting image now includes Python.
Think of RUN as:
👉 “Baking instructions into the image itself.”
2️⃣ What is CMD?
- Purpose: Defines the default command that runs when a container starts.
- Effect: Does not create a new image layer, but sets a startup instruction.
- Use Case: Starting the main process inside the container.
📌 Example:
FROM ubuntu:20.04
CMD ["echo", "Hello from the container!"]
Here, CMD runs echo when the container is launched:
docker build -t cmd-example .
docker run cmd-example
# Output: Hello from the container!
Think of CMD as:
👉 “What should this container do by default when it runs?”
3️⃣ Key Differences
| Feature | RUN | CMD |
|---|---|---|
| When executed | At build time | At container runtime |
| Effect | Creates a new image layer | Sets default container startup command |
| Use case | Install software, configure environment | Define entrypoint or app execution |
| Runs once or always? | Runs during image build | Runs every time container starts |
| Overridable? | No | Yes (docker run <image> <command> overrides CMD) |
4️⃣ Example: RUN vs CMD Together
FROM python:3.9
# Install dependencies at build time
RUN pip install flask
# Default command at runtime
CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0"]
RUN pip install flask→ Ensures Flask is already in the image.CMD [...]→ Defines what happens when the container starts.
If you run the container with a custom command:
docker run my-flask-image python3 --version
The CMD is overridden, and Docker runs python3 --version instead.
📌 Summary
- ✅
RUN→ Build-time instruction, creates an image layer (install, configure). - ✅
CMD→ Runtime instruction, defines container startup command. - ✅
CMDcan be overridden atdocker run, butRUNcannot.
👉 A simple way to remember:
RUN= Build step (permanent change to the image).CMD= Runtime step (default container behavior).