Some Docker instructions look similar and cause confusion for new developers using Docker. This post uses an example to illustrate the differences between Docker CMD, RUN, and ENTRYPOINT.
RUN executes the command on the new layer to create a new image. For example, often used to Install the software package.
CMD sets default commands and parameters that a running command line can override for Docker containers.
ENTRYPOINT setups a container that runs as an executable file.
Docker images and layers
When Docker runs the container, the images in it get to run. This image is usually created by running Docker instructions to add a layer on top of an existing image or OS distribution. The operating system distribution is the starting image and each layer added creates a new image.
The final Docker image resembles an internal OS distribution and some layers above it.
For example, with a series of deb packages and your application on top of Ubuntu 14.04 distribution.
Shell and Exec forms
All three statements (RUN, CMD, and ENTRYPOINT) can be specified in shell or exec form. Forms are usually more confusing than instructions themselves, so let’s understand these forms first.
FROM ubuntu RUN apt-get update -y RUN apt-get install python3 -y CMD echo "Hello world" ENTRYPOINT echo "Hello world"
Build the Docker image $ docker build-t test.
When instruction gets executed in shell form, it calls / bin / sh-c <command> under the hood and normal shell processing is performed. For example, the following snippet in Dockerfile
FROM ubuntu RUN apt-get update -y ENV name madhu sudhan ENTRYPOINT echo "Hello, $name"
$ docker build -t test1 .
If the container is running as Docker run -it test1 will produce output
Notice that the variable name has been replaced with that value.
This is the recommended format for the CMD and ENTRYPOINT commands.
<instruction> ["executable", "param1", "param2", ...]
RUN ["apt-get", "install", "python3"] CMD ["/bin/echo", "Hello world"] ENTRYPOINT ["/bin/echo", "Hello world"]
When the statement is executed in exec form, the executable is called directly and no shell processing occurs. For example, the following snippet in Dockerfile
FROM ubuntu RUN apt-get update -y ENV name madhu sudhan ENTRYPOINT ["/bin/echo", "Hello, $name"]
$ docker build -t test2.
If the container is running as docker run -it test2 will produce output
Note that variable names cannot be replaced.
How to run bash?
If you need to run bash (or an interpreter other than sh), use the exec form with /bin/bash as
Executable. In this case, normal shell processing is performed. For example a snippet from Dockerfile
FROM ubuntu RUN apt-get update -y ENV name madhu sudhan ENTRYPOINT ["/bin/bash", "-c", "echo Hello, $name"]
$ docker build -t test3.
If the container is running as docker run -it test3 will produce output
You can use the RUN instruction to install the application and the required packages. Run all commands on the current image and commit the result to create a new layer.
Often there are multiple RUN instructions in a Dockerfile.
There are two forms of RUN:
- RUN (shell form)
- RUN [“executable”, “param1”, “param2”] (exec form)
(See the Shell and Exec forms sections above for form details.)
A good example of a RUN instruction is to install a multiple version control systems package:
RUN apt-get update && apt-get install -y \ bzr \ cvs \ git \ mercurial \ subversion
Note that apt-get update and apt-get install are executed in a single RUN instruction. This is done to make sure that the latest packages are installed. If the apt-get install is included in another RUN instruction, layers added by the apt-get update that may have been created long ago will be reused.
You can use the CMD instruction to set a default command that runs only when you use it. Run the container with no commands. When you run the Docker container with a command, The default command is ignored. If your Dockerfile has multiple CMD instructions, all but the last statement the CMD instruction is ignored.
CMD has three forms: CMD ["executable","param1","param2"] (exec form, preferred) CMD ["param1","param2"] (sets additional default parameters for ENTRYPOINT in exec form) CMD command param1 param2 (shell form)
Again, the first and third forms are described in the Shell and Exec forms sections. The second is used in combination with the exec form in ENTRYPOINT instruction. Sets the default parameter that is added after the ENTRYPOINT parameter when running the container with no command-line arguments.
See, ENTRYPOINT for example.
Let’s see how the CMD command works. The following snippet of Dockerfile
FROM ubuntu RUN apt-get update -y CMD echo "Hello world"
$ docker build -t test4.
when the container runs as docker run -it test4 will produce output
However, if the container is running on a command. Example: docker run -it <image> /bin/bash, is CMD
Ignore it and run the bash interpreter instead.
$ docker run -it test4 /bin/bash
You can use the ENTRYPOINT instruction to configure the container to run as an executable file. this
It is similar to CMD in that you can also specify commands using parameters. The difference is that the ENTRYPOINT command and the Docker container do not ignore the parameters. It is executed with command line parameters. (There is a way to ignore the ENTTRYPOINT, but it’s unlikely that you can do it.)
ENTRYPOINT has two forms:
ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred) ENTRYPOINT command param1 param2 (shell form)
Be very careful when choosing the ENTRYPOINT form, as the forms behave very differently.
Exec form of ENTRYPOINT allows you to set commands and parameters and then use either
form of CMD to set additional parameters that are more likely to be changed. ENTRYPOINT
arguments are always used, while CMD ones can be overwritten by command line arguments
provided when the Docker container runs. For example, the following snippet in Dockerfile
FROM ubuntu RUN apt-get update -y ENTRYPOINT ["/bin/echo", "Hello"] CMD ["world"]
$ docker build -t test5.
when the container runs as docker run -it test5 will produce output
However, if the container is running as docker run -it test5 Reddy will result in
The ENTRYPOINT shell format ignores all CMD or Docker Run command line arguments.
The bottom line
Use the RUN statement to add a layer on top of the original image to build the image. When building an executable Docker image, ENTRYPOINT takes precedence over CMD, and commands are required Always run. In addition, use CMD if you need to specify additional default arguments this can be overwritten from the command line while the Docker container is running.
Select CMD if you need to provide default commands or possible arguments overridden from the command line when running the Docker container.