Whenever we are working on Docker, people often get confused between the commands like CMD and ENTRYPOINT which are mostly used while writing a Dockerfile. However, if you are a beginner and just started using Docker or you don’t have enough hands-on experience, this blog will help you to understand these commands in-depth with hands-on examples.
Before we begin, it is important to discuss the forms of instructions. Docker ENTRYPOINT and CMD can have two forms i.e, Shell form & Exec form.
For example -
<instruction> <command> ---> shell form
<instruction> ["executable", "parameter"] ---> execute
- CMD echo "Hello World" (shell form)
- CMD ["echo", "Hello World"] (exec form)
- ENTRYPOINT echo "Hello World" (shell form)
- ENTRYPOINT ["echo", "Hello World"] (exec form)
What is CMD & ENTRYPOINT?
Before moving ahead with the differences and some hands-on, let's try to understand what these are and why we need them. Both the parameters are used to specify the programs/commands to execute while initializing a container from docker image.
CMD: Sets default parameters that can be overridden from the Docker Command Line Interface (CLI) while running a docker container.
ENTRYPOINT: Default parameters that cannot be overridden while executing Docker Containers with CLI parameters.
Differences between CMD & ENTRYPOINT
As we discussed above, these are used to specify programs that execute when a container starts, but the major differences between the two are -
CMD commands are ignored by Daemon when there are parameters stated within the docker run command while ENTRYPOINT instructions are not ignored but instead are appended as command line parameters by treating those as arguments of the command.
Now, let’s take a closer look. We’ll use both command forms to go through the different stages of running a Docker container.
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 CMD instruction.
I have created a simple Dockerfile using Ubuntu as a base image and provided a CMD instruction.
FROM ubuntu CMD [“echo”, “Hello World”]
Now, let’s build an image out of this Dockerfile and run a container from the image created. To build an image with Dockerfile, use the following command -
docker build -t image-name .
To run a container out of the image build, execute the following command
docker run image-name
As you can see in the above image, there is no command-line argument given so the container will run the default CMD instruction and display the `Hello World` message. However, if you add an argument while starting a container, it overrides the CMD instructions given in Dockerfile .
In the above case, we passed a Linux command called `uname` which prints the basic system information.
Docker will run the container and use the `uname` command instead of CMD's echo command.
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.
However, in the case of ENTRYPOINT we 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.
We will again create a simple Dockerfile using ubuntu as a base image but this time providing an ENTRYPOINT command instead of CMD.
Now again, let’s build an image out of this Dockerfile and run a container from the image.
From the above image, we can observe that the output is the same as that of CMD but now let's provide an argument to see what output it shows.
As you can see docker did not override the initial instruction but took our argument as a parameter for echo instruction.
Later in the blog we will also discuss how we can override the ENTRYPOINT command but before that let's see how we can use ENTRYPOINT and CMD together.
ENTRYPOINT with CMD
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.
Note: If you are using both instructions, make sure to keep them in exec form.
First let's create a new Dockerfile with both the parameters stated
Now build the image and run it to see what output we get.
The output is correct as we expected it to be.
Now let's pass a parameter and see what output it shows
As you can see the ENTRYPOINT took ‘echo’ as instruction and CMD as a parameter that's why the parameter which we passed got overridden in CMD and later on ENTRYPOINT took it as a parameter.
For those folks who are wondering how we can override the ENTRYPOINT, let’s look into a simple example.
Let's use the ENTRYPOINT image as mentioned above and pass on --entrypoint flag in the docker run statement.
Execute the following command to override the ENTRYPOINT
docker run --entrypoint “command-to-override” image-name.
As we can see, instead of echo which we provided in our Dockerfile, the linux command we gave in CLI is being executed as the ENTRYPOINT and as soon as the container starts the
uname command gets executed.
Note: The command is only temporary. Once you exit out of the container and run it again using the standard docker run command, it executes the default ENTRYPOINT instruction.
Prefer ENTRYPOINT to CMD when building executable Docker images and you need a command always to be executed. Additionally, use CMD if you need to provide extra default arguments that could be overwritten from the command line when the docker container runs.
It is not necessary to use both the commands together, try to find your own use case while building the Dockerfile and select the appropriate command.
Hurray! You made it till the end hope you got a better understanding of how ENTRYPOINT and CMD works and when to use them in your own projects. Explore and try out this with different scenarios and feel free to comment down your queries. We would be happy enough to help you.