Unlike virtual machines, containers are not meant to host an operating system. Containers are just intended to run a specific task or process, such as to host an instance of a web application or database server. So who defines the task? ENTRYPOINT and/or CMD. They are two different Dockerfile instructions that both define programs to execute when the container starts running. But today we will focus on the difference between CMD and ENTRYPOINT.
The Difference between CMD and ENTRYPOINT
CMD defines default commands and/or parameters for a container. Even if no command is specified in the CLI, a default command/program executes with a CMD 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. For instance, you will simply see the “bash” as the default CMD command in the Dockerfile of an Ubuntu image (Figure 1)
ENTRYPOINT is used to set executables that will always run when the container is initiated. Unlike CMD commands, ENTRYPOINT commands cannot be ignored or overridden —even when the container runs with command line arguments stated, unless you add the
When to use CMD and/or ENTRYPOINT?
CMD is one of the best options when users do not input arguments in the command line. It specifies default programs that should run and ensures the container is in a running state (most of the time). Nevertheless, in specific use-cases, a docker run command can be executed through a CLI to override instructions specified within the Dockerfile.
ENTRYPOINT instructions are suitable for single-purpose and multi-mode images where there is a need for a specific command to always run when the container starts. (Creating executable image) One of its popular use-cases is building wrapper container-images that encapsulate legacy programs for containerization, which leverages an ENTRYPOINT instruction to ensure the program will always run.
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 vs. Exec Form
Before proceeding demonstration, it is important to understand the forms of instructions. Docker ENTRYPOINT and CMD can have two forms.
A shell form of instruction initiates processes that run within the shell. To execute this, invoke
/bin/sh -c <command>. Typically, every execution through a shell command requires environment variables to go through validation before returning the results.
<instruction> <command> CMD apt-get update
Unlike the shell command type, an instruction written in the executable form directly runs the executable binaries, without going through shell validation and processing.
<instruction> ["executable", "parameter"] CMD ["echo", "Hello World"]
However, try to keep all your instructions in exec form to prevent potential performance issues.
Creating a Dockerfile with CMD, Building an Image, and Running Containers
1. Start by creating a new
myhelloimage folder, and then move into that folder. After creating a Dockerfile in the folder, paste the one below into the file.
FROM ubuntu LABEL version=only_cmd RUN apt-get update -y CMD ["echo", "Hello World"]
2. Let’s build a Docker image from the newly made Dockerfile with docker
build -t <name> . Then we’ll create a container based on the image to see the container’s behavior with
docker run <imagename>.
As you see above CMD [“echo”, “Hello World”] instruction in our Dockerfile execute echo command and print “Hello World” as an output. What if we execute
docker run myhelloimage Mustafa command?
We get an error when we give the new parameter “Mustafa”. Try to overwrite both command and parameter as
docker run myimagehello echo Mustafa
Creating a Dockerfile with ENTRYPOINT, Building an Image, and Running Containers
1. No need to change the setup environment. We just need to change the Dockerfile. Please delete the former content and paste the following one.
FROM ubuntu LABEL version=only_entrypoint RUN apt-get update -y ENTRYPOINT ["echo", "Hello World"]
2. Build the image by using
docker build -t myhelloimage2 . Run the container with
docker run myhelloimage2
Above, notice that the container’s behavior built on Dockerfile with ENTRPOINT instructions is the same as the former one built by Dockerfile with CMD instructions. The point is that
docker run myhelloimage2 <parameter> will not give an error. Instead, it appends to the former output even if it is a command (echo). See below.
Creating a Dockerfile with both ENTRYPOINT and CMD, Building an Image, and Running Containers
1. For this time again you don’t need to change the setup environment. Just change the Dockerfile. Please delete the previous script and paste the following.
FROM ubuntu LABEL version=both CMD and ENTRPOINT RUN apt-get update -y ENTRYPOINT ["echo", "Hello"] CMD ["World"]
2. Build the image by using
docker build -t myhelloimage3 . Run the container with
docker run myhelloimage3
We get the same result with the time when we use only CMD or only ENTRYPOINT instructions. However, the output changes again once parameters are used. In this case, the default parameter “World” located in CMD instructions replaces our given parameter in the command line. The result remains the same when we try with two parameters (“Turkey”,”Ankara”) provided by CLI. Notice that the ENTRYPOINT command echo and parameter “Hello” are preserved each time.
This article shows the differences and similarities between the Docker instructions: CMD and ENTRYPOINT. We’ve observed at what point they get invoked. Also, we’ve taken a look at their uses and how they work together. After reading this article, you should better understand the difference between ENTRYPOINT and CMD in a Dockerfile. Explore both and experiment with them to find the best solution for you and please share your comment with us!