Skip to main content

[SOLVED] What is the difference between CMD and ENTRYPOINT in a Dockerfile? - docker

Understanding the Differences Between CMD and ENTRYPOINT in a Dockerfile

In Docker, it is important to know the difference between CMD and ENTRYPOINT in a Dockerfile. This helps us create better container applications. Both CMD and ENTRYPOINT tell how a Docker container runs when we start it. But they have different jobs and can change how our containers act. In this article, we will look into CMD and ENTRYPOINT. We will talk about what they do, when to use them, and show some examples.

Here’s what we will talk about in this chapter:

  • Solution 1 - Understanding CMD and ENTRYPOINT Basics
  • Solution 2 - When to Use CMD vs ENTRYPOINT
  • Solution 3 - Practical Example of CMD Usage
  • Solution 4 - Practical Example of ENTRYPOINT Usage
  • Solution 5 - Combining CMD and ENTRYPOINT
  • Solution 6 - Overriding CMD and ENTRYPOINT at Runtime
  • Conclusion

By the end of this article, we will understand how to use CMD and ENTRYPOINT in our Dockerfiles. This will help our applications run well in any environment. For more tips on using Docker and best practices, we can check out our articles on solving common Dockerfile issues and deploying minimal applications with Docker.

Solution 1 - Understanding CMD and ENTRYPOINT Basics

In a Dockerfile, we use CMD and ENTRYPOINT to define what commands run when we start a container. But they have different jobs and act in different ways.

CMD

  • Purpose: The CMD instruction tells Docker the default command to run if we start a container without giving a specific command. We can change it by adding a command when we run the container.

  • Usage: We can write the CMD instruction in three ways:

    1. Exec form (recommended):

      CMD ["executable", "param1", "param2"]

      This way does not use a command shell. It is the best way to ensure the arguments are handled correctly.

    2. Shell form:

      CMD command param1 param2

      This way runs the command in a shell (/bin/sh -c). It lets us use shell features, but it may cause problems with signals.

    3. Parameter form:

      CMD ["param1", "param2"]

      We use this only when we have ENTRYPOINT defined. It gives default parameters to the ENTRYPOINT command.

ENTRYPOINT

  • Purpose: The ENTRYPOINT instruction sets up a container that runs as an executable. It defines a command that we cannot change when we run the container, but we can add more arguments.

  • Usage: Like CMD, we can write ENTRYPOINT in two ways:

    1. Exec form (recommended):

      ENTRYPOINT ["executable", "param1", "param2"]

      This makes sure the command runs correctly without a shell getting in the way.

    2. Shell form:

      ENTRYPOINT command param1 param2

      This way runs the command in a shell, but it might not be the best for every situation.

Key Differences

  • Overriding Behavior:

    • We can override CMD by giving a command when we run docker run.
    • We cannot override ENTRYPOINT; the command we set will always run, but we can add more arguments.
  • Use Cases:

    • We use CMD for commands that we might want to change.
    • We use ENTRYPOINT for commands that should always run as the main process of the container.

We need to understand these differences to design our Docker containers well and make sure they work like we expect. For more information on Dockerfile usage, we can look at this guide about best practices for Dockerfiles.

Solution 2 - When to Use CMD vs ENTRYPOINT

In a Dockerfile, we use both CMD and ENTRYPOINT to define the command that runs when the container starts. But they have different uses. Knowing when to use CMD or ENTRYPOINT is really important for making good Docker images.

When to Use CMD

  • Default Command: We use CMD when we want to set the default command that runs when the container starts without changing it. CMD lets us define a command that can be replaced later.

    Example:

    FROM ubuntu:latest
    CMD ["echo", "Hello, World!"]
  • Flexibility: CMD is good when we want users to change the default command without changing the Dockerfile. This is helpful when the command might change.

    Example:

    FROM python:3.9
    CMD ["python", "app.py"]

When to Use ENTRYPOINT

  • Immutable Command: We use ENTRYPOINT when we want to set a command that should always run when the container starts. ENTRYPOINT sets the main command that is hard to change, so it gives consistent behavior.

    Example:

    FROM nginx:latest
    ENTRYPOINT ["nginx", "-g", "daemon off;"]
  • Command with Arguments: ENTRYPOINT is also good when we need to add extra arguments to the command. It lets us set the main command while CMD can set default arguments.

    Example:

    FROM redis:latest
    ENTRYPOINT ["redis-server"]
    CMD ["--port", "6379"]

Summary of Differences

  • Overriding: We can change CMD by giving a command when we run the container. But we can’t easily change ENTRYPOINT.
  • Purpose: We use CMD for default commands that might need changes. We use ENTRYPOINT for commands that must always run in a certain way.

By knowing these differences, we can choose better when to use CMD or ENTRYPOINT in our Dockerfiles. This helps us create more useful and friendly Docker images. For more examples on setting up Docker containers, we can look at this guide on Docker containers.

Solution 3 - Practical Example of CMD Usage

We use the CMD instruction in a Dockerfile to set the default command that runs when we start a container from the image. This lets us define the program and its options. A main point about CMD is that we can change it with command line options when we run the container.

Basic Syntax of CMD

There are three ways to write the CMD instruction:

  1. Exec form: This is the best way since it does not use a command shell. It also helps with handling signals better.

    CMD [ "executable", "param1", "param2" ]
  2. Shell form: This way runs the command in a shell. It can be good for shell features but may cause problems with signals.

    CMD executable param1 param2
  3. Default parameters: We can also use CMD to give default options to an ENTRYPOINT.

    CMD ["param1", "param2"]

Example of CMD Usage

Let us look at an example where we make a simple Docker image that runs a Python script.

  1. Create a Python script: First, we create a file called app.py with this content:

    # app.py
    import sys
    
    def main():
        print("Arguments passed to the script:", sys.argv[1:])
    
    if __name__ == "__main__":
        main()
  2. Create a Dockerfile: Next, we make a Dockerfile to set up the environment and show the CMD.

    # Dockerfile
    FROM python:3.9-slim
    
    WORKDIR /app
    
    COPY app.py .
    
    CMD ["python", "app.py"]

Building and Running the Docker Image

To build the Docker image, we run this command in the folder with our Dockerfile:

docker build -t my-python-app .

Now we can run the container:

docker run my-python-app arg1 arg2 arg3

Expected Output

When we run the container with arg1, arg2, and arg3, we will see this output:

Arguments passed to the script: ['arg1', 'arg2', 'arg3']

Key Points

  • The CMD instruction tells us the default command to run when the container starts.
  • We can change the default command by adding more command-line options when we run the container.
  • We should use the exec form of CMD to handle signals better and to avoid problems with the shell interpreting commands.

For more knowledge on Docker commands and how they work, we can check the article on Docker commands.

Solution 4 - Practical Example of ENTRYPOINT Usage

In a Dockerfile, we use the ENTRYPOINT instruction to define what will run when we start a container from the Docker image. The CMD gives default arguments for the command. But ENTRYPOINT is for setting the main command that should always run inside the container.

Syntax

We can write ENTRYPOINT in two ways: exec form and shell form.

  1. Exec Form:

    ENTRYPOINT ["executable", "param1", "param2"]

    We prefer this form. It lets us set the command and its parameters as a JSON array. This way, we avoid the shell’s processing.

  2. Shell Form:

    ENTRYPOINT command param1 param2

    This form runs the command in a shell.

Example of ENTRYPOINT Usage

Let’s look at a simple example. We want to make a Docker image that runs a Python script. We will use the exec form of ENTRYPOINT.

  1. Create a simple Python script called app.py:

    # app.py
    import sys
    
    if __name__ == "__main__":
        print("Arguments passed to the script:", sys.argv[1:])
  2. Create a Dockerfile that uses ENTRYPOINT:

    # Dockerfile
    FROM python:3.9-slim
    
    # Set the working directory
    WORKDIR /app
    
    # Copy the Python script into the container
    COPY app.py .
    
    # Set the ENTRYPOINT
    ENTRYPOINT ["python", "app.py"]
  3. Build the Docker image:

    Open your terminal. Go to the folder with the Dockerfile and the app.py script. Run this command:

    docker build -t my-python-app .
  4. Run the Docker container with arguments:

    docker run my-python-app arg1 arg2 arg3

    This command will show:

    Arguments passed to the script: ['arg1', 'arg2', 'arg3']

Combining ENTRYPOINT and CMD

We can also use ENTRYPOINT with CMD to give default arguments. For example:

# Dockerfile
FROM python:3.9-slim

WORKDIR /app
COPY app.py .

ENTRYPOINT ["python", "app.py"]
CMD ["default_arg1", "default_arg2"]

When we run the container without extra arguments, it will use the default values in CMD. But if we give arguments when running the container, those will replace the CMD values:

docker run my-python-app custom_arg1 custom_arg2

This will show:

Arguments passed to the script: ['custom_arg1', 'custom_arg2']

Using ENTRYPOINT well helps us make Docker containers that run specific applications or scripts with set behaviors. This makes it a strong tool in Dockerfile setups. For more tips on using Docker, we can check this guide on deploying a minimal Flask app.

Solution 5 - Combining CMD and ENTRYPOINT

In a Dockerfile, CMD and ENTRYPOINT have different roles. They help define how containers behave. We can combine them to make flexible and strong container setups. Knowing how to mix CMD and ENTRYPOINT helps us create a Docker image that works well and can change at runtime.

Using CMD with ENTRYPOINT

The ENTRYPOINT instruction tells what command will always run when the container starts. On the other hand, the CMD instruction gives default options for that command. When we use them together, CMD lets users change or add options to the ENTRYPOINT command.

Syntax

Here is the basic way to combine CMD and ENTRYPOINT:

ENTRYPOINT ["executable", "param1", "param2"]
CMD ["default_param1", "default_param2"]

Example

Let’s think of a case where we have a Python script we want to run in a Docker container. We can set the script as the ENTRYPOINT and use CMD for default options.

# Use a Python base image
FROM python:3.9-slim

# Set the working directory
WORKDIR /app

# Copy the Python script into the container
COPY myscript.py .

# Set the ENTRYPOINT to the Python interpreter and the script
ENTRYPOINT ["python", "myscript.py"]

# Set default arguments for the script
CMD ["--help"]

How It Works

  1. ENTRYPOINT: The command ["python", "myscript.py"] is fixed. This means every time the container starts, it will run the Python script.

  2. CMD: The default option is ["--help"]. This means if the container starts without extra options, it will show help for the script.

  3. Overriding CMD: Users can change the CMD options when they run the container. If we want to run the script with a different option, we can do:

    docker run myimage --version

    This command will run:

    python myscript.py --version

Benefits of Combining CMD and ENTRYPOINT

  • Flexibility: Users can give their own options without changing the Dockerfile.
  • Simplicity: We set the main behavior of the container once in ENTRYPOINT, and we can easily change defaults with CMD.
  • Clarity: It is clear which part of the command is fixed (ENTRYPOINT) and which part can change (CMD).

By combining CMD and ENTRYPOINT, we can make more reusable and versatile Docker images. This way is very useful for applications that need a default behavior but also want to let users change how it runs at runtime. This helps in different deployment situations. For more tips on Docker best practices, we can look at other resources like Dockerfile documentation.

Solution 6 - Overriding CMD and ENTRYPOINT at Runtime

In Docker, we can change both CMD and ENTRYPOINT at runtime. This lets us customize how our containers behave without needing to change the Dockerfile. This is very important for different deployment cases. Let’s see how we can do this.

Overriding CMD

To change the CMD instruction in a Dockerfile, we need to give a new command when we run the container. We do this using the docker run command. For example, if we have a Dockerfile like this:

FROM ubuntu:latest
CMD ["echo", "Hello from CMD"]

We can override it when we run the container like this:

docker run <image_name> ["echo", "Hello, World!"]

This command will replace the original CMD and it will run echo "Hello, World!" instead.

Overriding ENTRYPOINT

To change the ENTRYPOINT instruction, we use the --entrypoint flag in the docker run command. Let’s say we have a Dockerfile like this:

FROM ubuntu:latest
ENTRYPOINT ["top", "-b"]
CMD ["-c", "1"]

If we want to override the ENTRYPOINT, we can do it like this:

docker run --entrypoint /bin/bash <image_name>

This command will start a Bash shell instead of running the top command.

Overriding Both CMD and ENTRYPOINT

We can also change both CMD and ENTRYPOINT with one command. Here is how we can do it:

docker run --entrypoint /bin/bash <image_name> -c "echo 'Running bash instead of entrypoint'"

In this case, the container will run /bin/bash and execute -c "echo 'Running bash instead of entrypoint'". This will ignore both the CMD and ENTRYPOINT in the Dockerfile.

Conclusion

Changing CMD and ENTRYPOINT at runtime gives us great flexibility when we use Docker containers. We can customize how our applications run without changing the images. For more details on Docker commands and how to use them, we can check Docker Commands or look at Dockerfile Best Practices for better understanding. In conclusion, we need to understand the differences between CMD and ENTRYPOINT in a Dockerfile. This is important for defining how our containers behave.

We looked at their basic functions. We also discussed their use cases and gave some practical examples. Plus, we talked about how to change them at runtime.

This knowledge helps us improve our Docker skills. It also makes it easier to deploy applications. For example, you can check our guide on deploying minimal Flask apps.

If you want to learn more about Docker container management, we recommend our article on Docker commands.

Comments