DEV Community

Navee
Navee

Posted on

Docker: cmd VS entrypoint

Docker is widely used these days, but if you have not got any chance to work on it, then its high time to get familiar with it. This post is not going to be a tutorial about docker though, so it assumes that you have its basic understanding. If you know docker, you must know that to build a docker image, you need to create Dockerfile with several instructions in it. In this post, I am going to talk about two of those instructions: CMD and ENTRYPOINT which can be a bit confusing if you haven’t paid much attention to it.

Both of these docker instructions are used to define command/executables which is executed during container invocation. These are very similar but different instructions which can be used independently or together to achieve better flexibility to define what a container should execute. There are two ways/syntaxes to define them:

Exec form: (Preferred form)
CMD [“executable”, “arg1”, “arg2”]
ENTRYPOINT [“executable”, “arg1”, “arg2”]

Shell form:
CMD executable arg1 arg2
ENTRYPOINT executable arg1 arg2

Use cases:

CMD

Used to provide all the default scenarios which can be overridden.

Cmd instruction is used to define:

Default executable

This instructions is used to define a default executable for a container to execute. If you want to create a generic docker image, where users can pass any supported command to be executed on container invocation, then this instruction is the one to use. Entrypoint instruction should not be defined in Dockerfile for this use case.
CMD [“executable”, “arg1”, “arg2”]

Default arguments

This instruction can also be used to provide default arguments. For this use case, we don’t specify executable in this instruction at all, but simply define some arguments which are used as default/additional arguments for executable defined in the entrypoint instruction. Thus, entrypoint instruction is required in dockerfile for this use case to define an executable.
CMD [“arg1”, “arg2”]
ENTRYPOINT [“executable”]

P.S: Anything defined in CMD can be overridden by passing arguments in docker run command.

ENTRYPOINT

Used to define specific executable and arguments to be executed during container invocation which cannot be overridden. This is used to constraint the user to execute anything else. User can however define arguments to be passed in the executable by adding them in the docker run command.
ENTRYPOINT [“executable”, “arg1”, “arg2”]

Demo

For the demo, let's take the following dockerFile which fetches necessary cowsay and screenfetch libraries so that we can run these commands when running the container.

Demo 1 - Use of CMD to define Default executable

FROM debian:jessie-slim

RUN apt-get update                                      && \
    apt-get install -y --no-install-recommends             \
        cowsay                                             \
        screenfetch                                     && \
    rm -rf /var/lib/apt/lists/*

ENV PATH "$PATH:/usr/games"
CMD ["cowsay", "Yo, CMD !!"]

Build the Image:
docker build -t demo .

Run the container:
docker run demo

This will run the default executable specified in CMD instruction and output following.

Alt Text

However, you can override this executable, when running the container as
docker run demo screenfetch -E which will output

Alt Text

Demo 2 - Use of ENTRYPOINT

If you want to restrict users from passing any other executable, you can specify 'ENTRYPOINT' instruction as :

FROM debian:jessie-slim

RUN apt-get update                                      && \
    apt-get install -y --no-install-recommends          \
        cowsay                                          \
        screenfetch                             &&      \
    rm -rf /var/lib/apt/lists/*

ENV PATH "$PATH:/usr/games"

ENTRYPOINT ["cowsay", "Yo, Entrypoint!!"]

Build the image again and run this container as:
docker run demo

This will run the executable specified in ENTRYPOINT and output following.

Alt Text

With entryPoint defined in the docker file, if you pass an executable in the docker run command, it will not take that as an executable, but, as an argument for the executable defined in the entryPoint instruction. So if you run following command,

docker run demo screenfetch -E

It will output:

Alt Text

As expected, the arguments passed in the docker run command, is appended in the executable and argument, set in the entryPoint instruction.

Demo 3 - Use of ENTRYPOINT and CMD together

If Entrypoint is defined, anything defined in CMD will be taken as arguments for the executable defined in Entrypoint.

FROM debian:jessie-slim

RUN apt-get update                                      && \
    apt-get install -y --no-install-recommends          \
        cowsay                                          \
        screenfetch                             &&      \
    rm -rf /var/lib/apt/lists/*

ENV PATH "$PATH:/usr/games"

CMD ["Yo, CMD!!"]
ENTRYPOINT ["cowsay", "Yo, Entrypoint!!"]

Building the image from above docker file and running the container with docker run demo will output:

Alt Text

As you now know, the argument defined in CMD can easily be overridden by passing other arguments in docker run command, if you execute docker run demo Overriding arg passed in cmd, It will output:

Alt Text

Thus, the main point to remember is CMD is used to provide default executable and arguments, which can be overridden, while ENTRYPOINT is used to specify specific executable and arguments, to constraint the usage of image.

Discussion (11)

Collapse
maximization profile image
Maxim Orlov

Thank you for the clear explanation between the two.

FYI, the entrypoint can be overwritten as well with docker run --entrypoint docs.docker.com/engine/reference/c...

Collapse
lagerenas profile image
lagerenas

This is a great summary with clear examples. Thanks

Collapse
lianalupsa profile image
lianalupsa

Thanks ! Made my day !

Collapse
kapilsharma027 profile image
Kapil Sharma

Thank you very much , I was struggling from long time on this concept and finally got cleared...

Collapse
frankehlers profile image
Xeno

Awesome! After reading the docs, the differences were not clear to me. Your explanation is pretty simple :D

Collapse
amsaravi profile image
amsaravi

thanks for your illustrated approach and there is a short summary:
stackoverflow.com/a/21564990/13304305

Collapse
matheusdallrosa profile image
Matheus Dall'Rosa

Made my profile to be able to like this post.

Collapse
lasatadevi profile image
Navee Author

Thanx a lot Matheus. Your comment made my day :)

Collapse
hamalbi profile image
nefink

Just to the point. Even ater watching more than 20 youtube vids I was confused about this topic, finally this is what I was looking for. God bless you and looking forward to more such articles.

Collapse
gamespec2 profile image
Gamespec

A great example, thanks :)

remove virus using cmd

Collapse
rakeshdyx profile image
rakeshdyx

Great example!! It helped me clear my concept. Thank you!