RUN vs CMD vs Entrypoint in Docker

DockerOperating SystemOpen Source

The commands RUN, CMD and Entrypoint usually cause a lot of confusion among docker developers. Understanding all the three commands conceptually will help to have a clearer understanding of the same.

When we try to build an image using dockerfile, the instructions are executed step by step. The first instruction is usually pulling a base image such as an OS distribution like ubuntu, centos etc. After that, we modify the base image either by including more images using FROM and AS commands or by modifying the images. Every such instruction creates a new intermediate image build and for each of them, caches are created. The final docker image can be considered as a layered structure where there is a core or a base image and on top of that, there are several layered intermediate images.

To understand all these three commands in depth, we first need to understand what are shell and exec forms.

Executable form

This form is generally used for Entrypoint and CMD commands. It is of the form -

<instruction> [“executable”, “parameter”, “parameter”, ….]

When we execute an instruction in such a form, shell processing does not happen and the executable is called directly.

Consider the commands below.

RUN [“apt-get”, “install”, “vim”]
ENTRYPOINT [“/bin/echo”, “TutorialsPoint”]
CMD [“/bin/echo”, “TutorialsPoint”]

If we write a dockerfile with the following instructions,

ENV variable TutorialsPoint
ENTRYPOINT [“/bin/echo”, “$variable”]

When we try to run the image, the following output is generated.

$variable

Shell Form

When we try to execute an instruction using the shell form, normal shell processing takes place. It calls the command /bin/sh -c {command} behind the scenes.

It is of the form - <Your instruction> <the command>

Consider the commands below.

RUN apt-get -y update
CMD echo “TutorialsPoint”
ENTRYPOINT echo “TutorialsPoint”

The following dockerfile -

ENV variable TutorialsPoint
ENTRYPOINT echo “$variable”

will output -

TutorialsPoint

Now that we have understood the two forms in-depth, let us continue with the three commands.

RUN

The RUN command always gets executed in a new layer. It allows you to install packages and applications on top of an existing image layer and creates a new layer on top of it.

It can be written in both shell and exec forms. Examples include -

RUN apt-get -y update (shell form)
RUN [“apt-get”, “install”, “vim”] (exec form)

CMD

Using a CMD command, you will be able to set a default command. This will be executed if you run a particular container without specifying some command. In case you specify a command while running a docker container, the default one will be ignored. Note that if you specify more than one CMD instruction in your dockerfile, only the last one will be executed.

Following are the different ways, through which you can execute a CMD command.

  • CMD <command> parameter1, parameter2 …. (Shell form)

  • CMD [“executable command”, “parameter1”, “parameter2”, ….] (executable form)

  • CMD [“parameter1”, “parameter2”]

The third way is used to set some additional default parameters that will be inserted after the default parameters when you are using an ENTRYPOINT in executable form and if you run the container without specifying any arguments in the command line.

Consider the command below inside a dockerfile.

CMD echo “TutorialsPoint”

The output if you run it without specifying arguments (docker run -it image_name) will be -

TutorialsPoint

If you run it by specifying CLI arguments (docker run -it image_name /bin/bash), it will simply open a bash.

ENTRYPOINT

It looks similar to a CMD command. However, the difference is that it does not ignore the parameters when you run a container with CLI parameters. The two forms of ENTRYPOINT command are -

  • ENTRYPOINT <command> parameter1, parameter2, … (It is shell form)

  • ENTRYPOINT [“executable command”, “parameter1”, “parameter2”, ….] (Executable form)

When you use an executable form of ENTRYPOINT command, it will allow you to set additional parameters using CMD command. If you use it in shell form, it will ignore CMD parameters or any CLI arguments.

Consider the example below.

ENTRYPOINT [“/bin/echo”, “TutorialsPoint”]
CMD [“Docker”]
  • If you try to run the container without specifying any CLI arguments (docker run -it image_name), output will be - TutorialsPoint Docker

  • If you specify CLI arguments (docker run -it image_name DockerTutorials), output will be - TutorialsPoint DockerTutorials.

To conclude, if you want to specify default arguments and want it to be overwritten on specifying CLI arguments, use CMD commands. And if you want to run a container with the condition that a particular command is always executed, use ENTRYPOINT. RUN is simply used to build additional image layers over the base image.

raja
Published on 01-Oct-2020 19:13:26
Advertisements