Dockerfiles are the backbone of containerized applications, and two key instructions often used in Dockerfiles are CMD and ENTRYPOINT. While both are used to define how a container runs, they serve distinct purposes and are used differently. In this article, we will dive into the differences between CMD and ENTRYPOINT with real-world examples, so you can make informed decisions when building your Docker images.
What is CMD in Docker?
The CMD instruction is used to specify the default command and arguments to run when a container starts. However, if a user provides a command when running the container, it overrides the CMD instruction.
Syntax
CMD ["executable", "param1", "param2"] # Exec form
CMD command param1 param2 # Shell form
Example: Default Web Server
Here’s a Dockerfile that uses CMD to set up a simple Python HTTP server:
FROM python:3.9-slim
WORKDIR /app
CMD ["python", "-m", "http.server", "8000"]
When you build and run this image:
docker build -t python-server .
docker run -p 8000:8000 python-server
The container will start a web server on port 8000.
However, if you override the command:
docker run python-server python -c "print('Hello World')"
The CMD instruction is completely replaced, and the container runs the provided command instead.
What is ENTRYPOINT in Docker?
The ENTRYPOINT instruction is used to configure a container to run as an executable. Unlike CMD, arguments passed during docker run are appended to the ENTRYPOINT command rather than replacing it.
Syntax
ENTRYPOINT ["executable", "param1", "param2"] # Exec form
ENTRYPOINT command param1 param2 # Shell form
Example: Ping Utility
Here’s a Dockerfile that uses ENTRYPOINT to create a container for running ping commands:
FROM alpine:latest
ENTRYPOINT ["ping"]
When you build and run this image:
docker build -t ping-tool .
docker run ping-tool google.com
The google.com argument is appended to ping, and the container runs ping google.com.
Combining CMD and ENTRYPOINT
You can use both ENTRYPOINT and CMD together for more flexibility. In this setup, CMD provides default arguments to the ENTRYPOINT executable but can be overridden during runtime.
Example: Customizable Ping Tool
FROM alpine:latest
ENTRYPOINT ["ping"]
CMD ["localhost"]
- Default behavior:
Runsdocker run ping-toolping localhost. - Custom behavior:
Runsdocker run ping-tool google.comping google.com.
Key Differences Between CMD and ENTRYPOINT
| Feature | CMD | ENTRYPOINT |
|---|---|---|
| Purpose | Default command to run | Configures the container as an executable |
| Overridable | Fully overridden by docker run |
Arguments are appended to ENTRYPOINT |
| Syntax | Exec and shell forms | Exec and shell forms |
| Best Use Case | Default behavior with flexibility | Fixed behavior with optional arguments |
Real-World Use Cases
Case 1: Web Server
For a web server, CMD is preferred as it allows flexibility to override the default behavior if needed.
Case 2: CLI Tool
For command-line utilities or tools, ENTRYPOINT is ideal because it ensures the container always behaves as the tool, and users can pass arguments as needed.
Best Practices
- Use
CMDfor default commands that users might want to override. - Use
ENTRYPOINTfor containers designed as executables. - Combine
ENTRYPOINTandCMDfor default arguments with flexibility. - Always use the exec form (
["executable", "param1", "param2"]) to avoid issues with signal handling and process termination.
Conclusion
Understanding the differences between CMD and ENTRYPOINT is crucial for writing effective Dockerfiles. While CMD provides default commands, ENTRYPOINT ensures the container behaves predictably as an executable. By combining both instructions strategically, you can create flexible and robust Docker images tailored to your application’s needs.
