When building Docker images, two critical instructions you'll often encounter are ENTRYPOINT and CMD. While both define commands that a container executes when it starts, they serve distinct purposes. In this post, we’ll break down the differences between ENTRYPOINT and CMD and show how to use them effectively with real-world examples.
What Are ENTRYPOINT and CMD?
ENTRYPOINT
ENTRYPOINT defines the main command that always runs when the container starts. It is ideal when you want your container to execute a specific script or process consistently, regardless of additional user input. While ENTRYPOINT can accept arguments, the primary command is fixed.
CMD
CMD serves as a way to provide default arguments to ENTRYPOINT. If no ENTRYPOINT is defined, CMD acts as the primary command itself. The beauty of CMD is its flexibility—it can be overridden when running the container, making it ideal for specifying default behavior that can easily be customized.
Key Differences
-
ENTRYPOINTis used to define the main process that a container should always run. -
CMDsupplies default arguments toENTRYPOINT, or, if noENTRYPOINTis defined, it acts as the default command.
Example 1: Using a Command in ENTRYPOINT
In this first example, we’ll set a fixed command with ENTRYPOINT and provide a default argument with CMD.
Dockerfile:
# Base image
FROM alpine:latest
# Set ENTRYPOINT to a fixed command
ENTRYPOINT ["ping"]
# CMD provides default arguments to ENTRYPOINT
CMD ["google.com"]
Explanation:
-
ENTRYPOINTis set toping, meaning that command will always run when the container starts. -
CMDprovides the default argumentgoogle.comfor thepingcommand.
Building the docker image my-ping-image:
docker build -t my-ping-image:v1.0.0 . -f Dockerfile.ping
Running the container without arguments:
docker run --name google-ping-container my-ping-image:v1.0.0
This will execute:
ping google.com
Overriding CMD:
docker run --name localhost-ping-container my-ping-image:v1.0.0 localhost
This overrides CMD, and the container will now execute:
ping localhost
Example 2: Using a Shell Script in ENTRYPOINT with CMD for Environment-Specific Behavior
Now, let’s look at a more complex use case. We’ll use ENTRYPOINT to run a shell script that generates an index.html file dynamically based on the environment (development or production). The CMD will specify the environment, with a default of development.
Scenario:
You want to run an Nginx container that serves different content based on the environment. The index.html file will be created dynamically by a shell script using ENTRYPOINT, and the environment can be specified via CMD.
Dockerfile:
# Base image
FROM nginx:latest
# Install necessary utilities
RUN apt-get update && apt-get install -y bash
# Copy entrypoint script to the container
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
# Set ENTRYPOINT to the shell script
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# CMD provides default environment (development)
CMD ["development"]
Shell Script (entrypoint.sh):
#!/bin/bash
# Get the environment from CMD or default to development
ENVIRONMENT=$1
# Create the index.html file based on the environment
if [ "$ENVIRONMENT" == "development" ]; then
echo "<h1>Welcome to the Development Page</h1>" > /usr/share/nginx/html/index.html
else
echo "<h1>Welcome to the Production Page</h1>" > /usr/share/nginx/html/index.html
fi
# Start Nginx in the foreground
nginx -g 'daemon off;'
Explanation:
-
ENTRYPOINT: The script/usr/local/bin/entrypoint.shwill always run when the container starts. This script generates theindex.htmlfile based on the environment (either development or production). -
CMD: The default argument isdevelopment, so by default, the container will serve a "development" page.
Building the docker image my-nginx-app:
docker build -t my-nginx-app:v1.0.0 . -f Dockerfile.shell
Running the container without arguments (default to development):
docker run -d -p 8080:80 --name development-nginx-container my-nginx-app:v1.0.0
This will generate an index.html file containing:
<h1>Welcome to the Development Page</h1>
Visit http://localhost:8080 to see the development page.
Overriding CMD to run in production:
docker run -d -p 8081:80 --name production-nginx-container my-nginx-app:v1.0.0 production
This will generate an index.html file containing:
<h1>Welcome to the Production Page</h1>
Now, visiting http://localhost:8081 will show the production page.
Key Takeaways
-
ENTRYPOINTdefines a command that will always run when the container starts. It is well-suited for containers that must always perform a specific action (e.g., starting a web server or database). -
CMDprovides default arguments toENTRYPOINT. If there’s noENTRYPOINT,CMDacts as the primary command itself. It's flexible, allowing you to customize the behavior of your containers easily.
When to Use ENTRYPOINT
Use ENTRYPOINT when you need the container to run a specific process consistently, like a web server, background service, or database.
When to Use CMD
Use CMD to provide default arguments or when you want to allow users to override the command without altering the core functionality of the container.
Conclusion
By understanding the differences between ENTRYPOINT and CMD, you can build flexible, reusable Docker containers. ENTRYPOINT ensures that a container always performs a specific action, while CMD lets you adjust that behavior without changing the container's core functionality. Together, they provide a powerful combination for building efficient Docker images, as demonstrated by the examples above. Whether you're configuring a simple utility or dynamically creating environment-based content, mastering these instructions will enhance your Docker workflows.

Top comments (0)