Table of Contents
- Introduction
- The RUN Command: Your Image Builder
- The CMD Command: Your Default Instructions
- The ENTRYPOINT: Your Container's Primary Purpose
- How They Work Together
- Common Use Cases
- Best Practices
- Quick Reference Table
- Example: Putting It All Together
- Conclusion
Introduction
When working with Docker, understanding the difference between RUN, CMD, and ENTRYPOINT is key to effectively managing how containers are executed. These commands serve different purposes in controlling the behavior of a container when it's started.
The RUN Command: Your Image Builder
Think of RUN as your container's construction worker. It executes during the image build process, setting up your environment.
Here's what RUN does:
- Installs packages
- Creates directories
- Copies files
- Sets up your environment
Example:
FROM python:3.9 RUN apt-get update RUN pip install flask RUN mkdir /app
Each RUN command creates a new layer in your image. It's like adding a new floor to a building - permanent and part of the structure.
The CMD Command: Your Default Instructions
CMD is like leaving a note saying "here's what to do if no one says otherwise." It provides default commands or parameters that can be easily overridden.
Key points about CMD:
- You can only have one
CMDinstruction in a Dockerfile - It can be overridden from the command line
- It specifies the default program that should run in your container
There are three forms of CMD:
# Shell form CMD python app.py # Exec form (preferred) CMD ["python", "app.py"] # Parameters for ENTRYPOINT CMD ["--port", "8080"]
The ENTRYPOINT: Your Container's Primary Purpose
ENTRYPOINT defines your container's main executable. Think of it as your container's mission in life - it's what the container is designed to do.
Two forms of ENTRYPOINT:
# Shell form ENTRYPOINT python app.py # Exec form (preferred) ENTRYPOINT ["python", "app.py"]
How They Work Together
The real magic happens when you combine these commands. Here's how they interact:
RUNsets up your environmentENTRYPOINTsets the main executableCMDprovides default arguments
Example:
FROM python:3.9 # Setup phase RUN pip install flask RUN mkdir /app WORKDIR /app COPY . . # Runtime configuration ENTRYPOINT ["python"] CMD ["app.py", "--port", "8080"]
In this case:
- If you run the container normally: It executes
python app.py --port 8080 - If you run with arguments:
docker run myimage script.py, it runspython script.py
Common Use Cases
Web Server Example
FROM nginx:alpine RUN mkdir -p /usr/share/nginx/html COPY ./website /usr/share/nginx/html ENTRYPOINT ["nginx"] CMD ["-g", "daemon off;"]
Application Server Example
FROM node:14 RUN mkdir /app WORKDIR /app COPY package*.json ./ RUN npm install COPY . . ENTRYPOINT ["node"] CMD ["server.js"]
Best Practices
-
For RUN:
- Use for installation and setup
- Combine related commands with
&&to reduce layers - Clean up after installations
-
For CMD:
- Always use the exec form
["executable", "param1", "param2"] - Use for default parameters that might need to change
- Remember it can be overridden at runtime
- Always use the exec form
-
For ENTRYPOINT:
- Use for commands that shouldn't change
- Combine with CMD for flexible defaults
- Always use exec form for predictable behavior
Quick Reference Table
| Command | Purpose | Can Override? | Multiple Allowed? |
|---|---|---|---|
| RUN | Build-time setup | No | Yes |
| CMD | Default runtime command/args | Yes | No (last one wins) |
| ENTRYPOINT | Container's main executable | Yes (--entrypoint) | No (last one wins) |
Example: Putting It All Together
Here's a complete example showing all three commands working together:
FROM python:3.9 # RUN commands for setup RUN apt-get update && \ apt-get install -y --no-install-recommends \ postgresql-client && \ rm -rf /var/lib/apt/lists/* RUN pip install flask psycopg2-binary # Setup application WORKDIR /app COPY . . # Set the main executable ENTRYPOINT ["python"] # Set default arguments CMD ["app.py", "--host", "0.0.0.0", "--port", "8080"]
In this example:
RUNinstalls dependencies and sets up the environmentENTRYPOINTspecifies that Python is our main executableCMDprovides default arguments that can be overridden
Conclusion
Understanding the differences between RUN, CMD, and ENTRYPOINT is crucial for Docker mastery:
- Use
RUNfor building your image and setting up the environment - Use
CMDfor default commands and arguments that might change - Use
ENTRYPOINTfor the main executable that defines your container's purpose
Remember: RUN executes during build, while CMD and ENTRYPOINT determine what happens when your container starts. Happy Dockerizing!