Understanding Docker ENTRYPOINT vs CMD: Key Differences and Practical Examples

sre_panchanan

Panchanan Panigrahi

Posted on September 15, 2024

Understanding Docker ENTRYPOINT vs CMD: Key Differences and Practical Examples

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

  • ENTRYPOINT is used to define the main process that a container should always run.
  • CMD supplies default arguments to ENTRYPOINT, or, if no ENTRYPOINT is 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"]
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • ENTRYPOINT is set to ping, meaning that command will always run when the container starts.
  • CMD provides the default argument google.com for the ping command.

Building the docker image my-ping-image:

docker build -t my-ping-image:v1.0.0 . -f Dockerfile.ping
Enter fullscreen mode Exit fullscreen mode

Running the container without arguments:

docker run  --name google-ping-container my-ping-image:v1.0.0
Enter fullscreen mode Exit fullscreen mode

This will execute:

ping google.com
Enter fullscreen mode Exit fullscreen mode

Overriding CMD:

docker run  --name localhost-ping-container my-ping-image:v1.0.0 localhost
Enter fullscreen mode Exit fullscreen mode

This overrides CMD, and the container will now execute:

ping localhost
Enter fullscreen mode Exit fullscreen mode

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"]
Enter fullscreen mode Exit fullscreen mode

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;'
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • ENTRYPOINT: The script /usr/local/bin/entrypoint.sh will always run when the container starts. This script generates the index.html file based on the environment (either development or production).
  • CMD: The default argument is development, 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
Enter fullscreen mode Exit fullscreen mode

Running the container without arguments (default to development):

docker run -d -p 8080:80 --name development-nginx-container my-nginx-app:v1.0.0
Enter fullscreen mode Exit fullscreen mode

This will generate an index.html file containing:

<h1>Welcome to the Development Page</h1>
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:8080 to see the development page.

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
Enter fullscreen mode Exit fullscreen mode

This will generate an index.html file containing:

<h1>Welcome to the Production Page</h1>
Enter fullscreen mode Exit fullscreen mode

Now, visiting http://localhost:8081 will show the production page.

Production Page

Key Takeaways

  • ENTRYPOINT defines 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).
  • CMD provides default arguments to ENTRYPOINT. If there’s no ENTRYPOINT, CMD acts 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.

💖 💪 🙅 🚩
sre_panchanan
Panchanan Panigrahi

Posted on September 15, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related