Table of Contents
In this article, we will see the difference between Docker CMD and ENTRYPOINT with the help of examples. According to Docker official documentation, both CMD and ENTRYPOINT instructions define what command gets executed when running a container. But often it becomes very confusing for lot of people to understand the difference and usage of both of these instruction. To understand more about its usage, you need to first understand the rules given in the documentation:-
- Dockerfile should specify at least one of CMD or ENTRYPOINT commands.
- ENTRYPOINT should be defined when using the container as an executable.
- CMD should be used as a way of defining default arguments for an ENTRYPOINT command or for executing an ad-hoc command in a container.
- CMD will be overridden when running the container with alternative arguments.
Docker CMD vs ENTRYPOINT
Also Read: 40 Ultimate docker commands with examples | Cheat Sheet
1. CMD
If you want to always run a specific command inside a docker container then one option you have is to hard code that command using CMD instruction. So that whenever you start the container, it will run that command inside the container. So here basically command argument is fixed and nothing can be overridden. To explain this further, Let's take a simple example of below Dockerfile where we are using the alpine 3.14
base image and passing bash command sleep 5
in the CMD instruction. While there are multiple ways to pass bash command in CMD instruction but we will stick to the JSON way of writing.
root@localhost:~# nano Dockerfile
FROM alpine:3.14
CMD ["sleep", "5"]
When you build the above dockerfile using docker build -t demo . command then it should build like below.
root@localhost:~# docker build -t demo .
Sending build context to Docker daemon 12.23GB
Step 1/2 : FROM alpine:3.14
3.14: Pulling from library/alpine
97518928ae5f: Pull complete
Digest: sha256:635f0aa53d99017b38d1a0aa5b2082f7812b03e3cdb299103fe77b5c8a07f1d2
Status: Downloaded newer image for alpine:3.14
---> 0a97eee8041e
Step 2/2 : CMD ["sleep", "5"]
---> Running in 8f13e4975685
Removing intermediate container 8f13e4975685
---> e5edd4d8b443
Successfully built e5edd4d8b443
Successfully tagged demo:latest
Now when you run this container using docker run demo
command then it should run sleep 5
command inside the container due which you will see below command will make container sleep for 5 secs before getting exited out.
root@localhost:~# docker run demo
The other option that you have is to completely override the command given in CMD by passing different command during the start of the container. This will override any command given in CMD instruction. For example, you can simply run docker run demo pwd
command. It will override the sleep 5
with pwd
command and gives you the output of pwd
instead of sleep 5
.
root@localhost:~# docker run demo pwd
/
2. ENTRYPOINT
As you have seen above, CMD is always used when you have to run some fixed command inside a container. But what about a case where you always need to change only the command argument and not the command itself. In that case CMD will no longer be useful. For those cases, you need to use ENTRYPOINT. Using this docker instruction, you can just pass the bash command inside ENTRYPOINT and argument can be passed at the time of starting the container.
root@localhost:~# nano Dockerfile
FROM alpine:3.14
ENTRYPOINT ["sleep"]
You can build the above image using same docker build -t demo .
command.
root@localhost:~# docker build -t demo .
Sending build context to Docker daemon 12.23GB
Step 1/2 : FROM alpine:3.14
---> 0a97eee8041e
Step 2/2 : ENTRYPOINT ["sleep"]
---> Running in 63c4190b0cdf
Removing intermediate container 63c4190b0cdf
---> 2b97d9da58b1
Successfully built 2b97d9da58b1
Successfully tagged demo:latest
Once the build is successful, you can run the container using docker run demo 5
command. It basically means that you are running sleep 5
command during the start of the container. So when you run this, you will notice that container will sleep for 5 seconds before it get exited out.
root@localhost:~# docker run demo 5
If you now try to run different command or pass any argument which was not expected by sleep command then you will see an error on the output like below. This also confirms that you cannot override the command given in the ENTRYPOINT instruction.
root@localhost:~# docker run demo pwd
sleep: invalid number 'pwd'
3. Using both CMD and ENTRYPOINT
You might also encounter a scenario where you need to do both that is, pass only the argument to the command or override the complete command or sometimes may use only the command without any arguments. So for cases like this where you need to configure a default value, it is always recommended to use both ENTRYPOINT and CMD together. ENTRYPOINT will allow arguments to be passed to the command and CMD will allow the command to be completely overridden with new command at the start of the container. So now the Dockerfile will look like this.
root@localhost:~# nano Dockerfile
FROM alpine:3.14
ENTRYPOINT ["sleep"]
CMD ["10"]
If you now build this Image using docker build -t demo .
command then it should look like below.
root@localhost:~# docker build -t demo .
Sending build context to Docker daemon 12.23GB
Step 1/3 : FROM alpine:3.14
---> 0a97eee8041e
Step 2/3 : ENTRYPOINT ["sleep"]
---> Using cache
---> 2b97d9da58b1
Step 3/3 : CMD ["10"]
---> Running in 34f1645489cc
Removing intermediate container 34f1645489cc
---> 44eacfa0dec2
Successfully built 44eacfa0dec2
Successfully tagged demo:latest
Finally run the container without any command or argument. By default, this should run sleep 10
command inside the container.
root@localhost:~# docker run demo