Docker CMD vs. Entrypoint Commands: What's the Difference?

February 18, 2020

Introduction

Containers are designed for running specific tasks and processes, not for hosting operating systems. You create a container to serve a single unit task. Once it completes the given task, it stops. Therefore, the container life-cycle depends on the ongoing process inside of it. Once the process stops, the container stops as well.

A Dockerfile defines this process. It is a script made up of instructions on how to build a Docker image. In this script, there are two types of instructions that can define the process running in the container:

  • ENTRYPOINT
  • CMD

In this article, we explain the differences between Docker ENTRYPOINT and CMD and when to use which Docker instruction.

What is the difference between CMD and Entrypoint?

Docker Entrypoint vs CMD: Solving the Dilemma 

In short, CMD defines default commands and/or parameters for a container. CMD is an instruction that is best to use if you need a default command which users can easily override. If a Dockerfile has multiple CMDs, it only applies the instructions from the last one.

On the other hand, ENTRYPOINT is preferred when you want to define a container with a specific executable. You cannot override an ENTRYPOINT when starting a container unless you add the --entrypoint flag.

Combine ENTRYPOINT with CMD if you need a container with a specified executable and a default parameter that can be modified easily. For example, when containerizing an application use ENTRYPOINT and CMD to set environment-specific variables.

Shell and Exec Form

Before we begin, it is important to discus the forms of instructions. Docker ENTRYPOINT and CMD can have two forms:

  • Shell form
  • Exec form

The syntax for any command in shell form is:

<instruction> <command>

The syntax for instructions in exec form is:

<instruction> ["executable", "parameter"]

You can write Docker CMD/ENTRYPOINT instructions in both forms:

  • CMD echo "Hello World" (shell form)
  • CMD ["echo", "Hello World"] (exec form)
  • ENTRYPOINT echo "Hello World" (shell form)
  • ENTRYPOINT ["echo", "Hello World"] (exec form)

However, try to keep all your instructions in exec form to prevent potential performance issues.

Docker CMD

Docker CMD defines the default executable of a Docker image. You can run this image as the base of a container without adding command-line arguments. In that case, the container runs the process specified by the CMD command.

The CMD instruction is only utilized if there is no argument added to the run command when starting a container. Therefore, if you add an argument to the command, you override the CMD.

To show you how CMD works, we will create a sample container with a CMD instruction.

Creating a Dockerfile with CMD and Building an Image

1. Start by creating a new MyDockerImage folder to store your images in:

sudo mkdir MyDockerImage

2. Move into that folder and create a new Dockerfile:

cd MyDockerImage
sudo touch Dockerfile

3. Open the Dockerfile with your favorite text editor:

nano Dockerfile

4. Then, add the following content to the file:

FROM ubuntu
MAINTAINER sofija
RUN apt-get update
CMD ["echo", "Hello World"]

In the content above, you can see that we used the CMD instruction to echo the message Hello World when the container starts up without a specified command.

5. Save and exit the file.

6. The next step is to build a Docker image from the newly made Dockerfile. Since we are still in the MyDockerImage directory, you don’t need to specify the location of the Dockerfile, just build the image by running:

sudo docker build .

7. The output will tell you the name of the container. You can check to see whether it is available among the locally stored images by running:

sudo docker images
Find Docker image among locally listed images.

Note: In this step, you have created a Docker image and stored it into your local repository. If you want to learn more about this process, refer to our article on creating Docker images with Dockerfiles.

Running a Docker Container with CMD

To see CMD in action, we’ll create a container based on the image made in the previous step.
Run the container with the command:

sudo docker run [image_name]
Starting a container to test Docker CMD instruction.

Since there is no command-line argument, the container will run the default CMD instruction and display the Hello World message. However, if you add an argument when starting a container, it overrides the CMD instruction.

For example, add the hostname argument to the docker run command:

sudo docker run [image_name] hostname

Docker will run the container and the hostname command instead of the CMD’s echo command. You can see this in the output.

Example of how to override Docker CMD when starting a container.

Docker Entrypoint

ENTRYPOINT is the other instruction used to configure how the container will run. Just like with CMD, you need to specify a command and parameters.

What is the difference between CMD and ENTRYPOINT? You cannot override the ENTRYPOINT instruction by adding command-line parameters to the docker run command. By opting for this instruction, you imply that the container is specifically built for such use.

Read on to see how we apply ENTRYPOINT in container creation.

Creating a Dockerfile with ENTRYPOINT and Building an Image

1. Use the Dockerfile created in the CMD section and edit the file to change the instruction. Open the existing file with a text editor:

sudo nano Dockerfile

2. Edit the content by replacing the CMD command with ENTRYPOINT:

FROM ubuntu
MAINTAINER sofija
RUN apt-get update
ENTRYPOINT ["echo", "Hello World"]
Dockerfile Entrypoint example.

3. Save and close the file.

Running a Docker Container with ENTRYPOINT

1. Build a new image using the following command:

sudo docker build .

2. The output should show you have successfully built the new image under a given name. Now let’s run it as a container without adding any command-line parameters:

sudo docker run [container_name]
Running a container using Docker Entrypoint.

The output will be the same as with CMD. This is because we haven’t added any arguments to the run command.

3. To see how ENTRYPOINT works, you need to add a parameter when starting a container. Use the same command as in the previous step and add something after the container name:

sudo docker run [container_name] KnowledgeBase
Example of how Docker override entrypoint by adding new parameters.

As you see, Docker did not override the initial instruction of echoing Hello World. It merely added the new parameter to the existing command.

Note: There is a way to override the ENTRYPOINT instruction – you need to add the --entrypoint flag prior to the container_name when running the command.

Although you can use ENTRYPOINT and CMD in both forms, it is generally advised to stick to exec form. This is the more reliable solution as shell form can occasionally bring about subtle issues in the process.

Docker Entrypoint with CMD

As you have seen so far, ENTRYPOINT and CMD are similar, but not the same. What’s more, these two instructions are not mutually exclusive. That’s right, it is possible to have both in your Dockerfile.

There are many situations in which combining CMD and ENTRYPOINT would be the best solution for your Docker container. In such cases, the executable is defined with ENTRYPOINT, while CMD specifies the default parameter.

If you are using both instructions, make sure to keep them in exec form.

Read on to see how ENTRYPOINT and CMD collaborate in our example.

Run a Container with Entrypoint and CMD

1. First, we are going to modify our existing Dockerfile so it includes both instructions. Open the file with:

sudo nano Dockerfile

2. The file should include an ENTRYPOINT instruction specifying the executable, as well as a CMD instruction defining the default parameter which should appear if no additional ones are added to the run command:

FROM ubuntu
MAINTAINER sofija
RUN apt-get update
ENTRYPOINT ["echo", "Hello"]
CMD ["World"]
An example of a Dockerfile with ENTRYPOINT and CMD together.

3. Now, build a new image from the modified Dockerfile:

sudo docker build . 

4. Let’s test the container by running it without any parameters. Enter the command:

sudo docker run [container_name]
Docker ENTRYPOINT vs CMD instructions combined.

It will return the message Hello World. However, what happens when we add parameters to the docker run command?

5. Use the same command again, but this time add your name to the run command:

sudo docker run [container_name] [your_name]
Adding parameters to a docker run command to run a container with ENTRYPOINT and CMD instructions.

The output has now changed to Hello [your_name](in my case, it’s Hello Sofija). This is because you cannot override ENTRYPOINT instructions, whereas with CMD you can easily do so.

Conclusion

After reading this article, you should have a better understanding of the difference between ENTRYPOINT and CMD. Explore the use of both and experiment with them to find the best solution for you.

If you are new to Docker, check out our Docker cheat sheet with all the common commands. We’re sure it will come in handy!

Was this article helpful?
YesNo
Sofija Simic
Sofija Simic is an experienced Technical Writer. Alongside her educational background in teaching and writing, she has had a lifelong passion for information technology. She is committed to unscrambling confusing IT concepts and streamlining intricate software installations.
Next you should read
How to Manage Docker Containers? Best Practices
January 29, 2019

With Docker Container Management you can manage complex tasks...
Read more
How To Remove Docker Images, Containers, Networks & Volumes
February 7, 2019

Docker allows users to create a container in which an application or process...
Read more
How to Set Up and Use Private Docker Registry
December 5, 2019

By setting up a private Docker registry, you can save valuable resources and...
Read more
Docker ADD vs COPY: What are the Differences?
December 16, 2019

If you are creating a Dockerfile, you may be puzzled by how to copy files...
Read more