ENTRYPOINT vs. CMD in Dockerfile
- Views
Both ENTRYPOINT and CMD allow you to specify the startup command for an image, but there are subtle differences between them. There are many times where you’ll want to choose one or the other, but they can also be used together. We’ll explore the similarity and difference of the two instructions in below section.
Similarities
Both the ENTRYPOINT and CMD instructions support two different forms: the shell form and the exec form
When using the shell form, the specified binary is executed with an invocation of the shell using
/bin/sh -c
When the exec form is used the command will be executed without a shell. This means that normal shell processing does not happen e.g it will not do variable substitution
The exec form is preferred form for both of the two instructions.
The ENTRYPOINT or CMD that you specify in your Dockerfile identify the default executable for your image. However, the user has the option to override either of these values at run time
We can override the default CMD by specifying an argument after the image name when starting the container:
docker run <image name> commands
The default ENTRYPOINT can be similarly overridden but it requires the use of the
--entrypoint
flag
When multiple ENTRYPOINT or CMD specified in a Dockerfile, only the last one will take effect respectively
Differences
ENTRYPOINT
ENTRYPOINT command and parameters are not ignored when Docker container runs with command line parameters
ENTRYPOINT should be used in scenarios where you want the container to behave exclusively as if it were the executable it’s wrapping. That is, when you don’t want or expect the user to override the executable you’ve specified
In an exec form ENTRYPOINT, command line arguments to
docker run <image>
will be appended after all elements, and will override all elements specified using CMDThe shell form prevents any CMD or run command line arguments from being used
The disadvantage of the shell form is that your ENTRYPOINT will be started as a subcommand of
/bin/sh -c
, which does not pass signals. This means that the executable will not be the container’s PID 1 - and will not receive Unix signals - so your executable will not receive a SIGTERM fromdocker stop <container>
. However, you can useexec
before your binary in the shell form to make the executable be the container’s PID 1
CMD
CMD instruction allows you to set a default command, which will be executed only when you run container without specifying a command
If the user specifies arguments to docker run then they will override the default command specified in CMD
CMD has another form:
CMD ["param1","param2"]
(as default parameters to ENTRYPOINT), which is used with ENTRYPOINT togetherIf CMD is used to provide default arguments for the ENTRYPOINT instruction, both the CMD and ENTRYPOINT instructions should be specified with the JSON array format
Use ENTRYPOINT and CMD Together
Combining ENTRYPOINT and CMD allows you to specify the default executable for your image while also providing default arguments to that executable which may be overridden by the user
Both CMD and ENTRYPOINT instructions define what command gets executed when running a container. There are few rules that describe their co-operation. The table below shows what command is executed for different ENTRYPOINT / CMD combinations:
No ENTRYPOINT | ENTRYPOINT exec_entry p1_entry | ENTRYPOINT [“exec_entry”, “p1_entry”] | |
---|---|---|---|
No CMD | error, not allowed | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry |
CMD [“exec_cmd”, “p1_cmd”] | exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry exec_cmd p1_cmd |
CMD [“p1_cmd”, “p2_cmd”] | p1_cmd p2_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry p1_cmd p2_cmd |
CMD exec_cmd p1_cmd | /bin/sh -c exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd |
Conclusions and Hints
The main purpose of a ENTRYPOINT is to configure a container that will run as an executable
The main purpose of a CMD is to provide defaults for an executing container
Prefer ENTRYPOINT to CMD when building executable Docker image 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 command line when docker container runs
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
If you need to write a starter script for a single executable, you can ensure that the final executable receives the Unix signals by using
exec
andgosu
commandsThe exec form is parsed as a JSON array, which means that you must use double-quotes (“) around words not single-quotes (‘)