What is the difference between CMD and ENTRYPOINT in Dockerfile ?
This tutorial explains you the difference between CMD and ENTRYPOINT commands usage in Dockerfile. You will also learn when to use CMD instead of ENTRYPOINT for your docker containers.
Dockerfile image defaults – CMD and ENTRYPOINT
When developers builds an image from Dockerfile or commits it, they can set number of default parameters that takes effect the the docker containers starts up.
Note, the following four docker commands cannot be overriden during runtime: FROM, MAINTAINER, RUN and ADD. And for other commands you have corresponding override in docker run command.
CMD default command in Dockerfile
CMD default command defines the default executable of a docker image. This command can be a default command or optional because the person who had created the docker image would have already provided this default command using CMD instruction in the Dockerfile. In this case the docker container runs the process specified by the CMD instruction.
The following is the sample dockerfile which uses CMD instruction which user can easily override by specifying new command in docker run command.
Dockerfile
FROM ubuntu MAINTAINER Sneppets Admin <[email protected]> RUN apt-get update && apt-get install -y openssh-server RUN mkdir -p /var/run/sshd RUN useradd -ms /bin/bash admin ADD sshd_config /etc/ssh/sshd_config CMD /usr/sbin/sshd -D USER admin WORKDIR /tmp ENV hello "Hello World"
In the above example, you dockerize SSH service using openssh-server, add new user to the docker container and use CMD instruction CMD /usr/sbin/sshd -D . The image that will be created by default has command which tells the docker container to run sshd daemon by default.
The following commands shows how to build image with default command, check docker images, run docker image and check docker containers that are running.
//build image (default CMD command) $ docker build -t sneppets/sshd-example . //list docker images $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE sneppets/sshd-example latest 87737afac12e 4 minutes ago 222MB ubuntu latest 1e4467b07108 2 days ago 73.9MB //run container $ docker run sneppets/sshd-example //list running containers (Runs sshd daemon) $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d68a7e00f10b sneppets/sshd-example "/bin/sh -c '/usr/sb…" 34 seconds ago Up 32 seconds gracious_lalande
Note, this CMD instruction will be utilized only if there is no argument specified in the docker run command which overrides CMD when starting a container. For example, let’s add the hostname argument to the docker run command as shown below.
$ docker run sneppets/sshd-example hostname 7329181f6f84
In the above case, docker container will run and the hostname command will get executed instead of CMD /usr/sbin/sshd -D as shown below. Therefore, user can override CMD default command easily.
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7329181f6f84 sneppets/sshd-example "hostname" 9 seconds ago Exited (0) 8 seconds ago vibrant_noether
ENTRYPOINT default command in Dockerfile
ENTRYPOINT default command is another type of instruction or command used to define default executable of a docker image. Similar to CMD, you need to specify a command and parameters. Below is the sample Dockerfile for the same.
Dockerfile
Replace CMD /usr/sbin/sshd -D with ENTRYPOINT /usr/sbin/sshd -D as shown below.
FROM ubuntu MAINTAINER Sneppets Admin <[email protected]> RUN apt-get update && apt-get install -y openssh-server RUN mkdir -p /var/run/sshd RUN useradd -ms /bin/bash admin ADD sshd_config /etc/ssh/sshd_config ENTRYPOINT /usr/sbin/sshd -D USER admin WORKDIR /tmp ENV hello "Hello World"
Try building image and run docker container with ENTRYPOINT command as default command with the following steps.
//build image (default CMD command) $ docker build -t sneppets/sshd-example2 . //list docker images $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE sneppets/sshd-example2 latest cf6d05ced818 5 seconds ago 222MB sneppets/sshd-example latest 87737afac12e 35 minutes ago 222MB ubuntu latest 1e4467b07108 2 days ago 73.9MB //run container $ docker run sneppets/sshd-example2 //list running containers (Runs sshd daemon) $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES adcd98237607 sneppets/sshd-example2 "/bin/sh -c '/usr/sb…" 6 seconds ago Up 5 seconds gracious_hertz
You cannot override an ENTRYPOINT command when starting a container unless you add the –entrypoint flag as shown in the following example. So basically, you are making a container locked to a particular command or locked with specific executable if you don’t use –entrypoint flag.
//Override ENTRYPOINT default command using --entrypoint command $ docker run -it --entrypoint /bin/bash sneppets/sshd-example2 root@e2c3c9b39853:/# exit exit //list running docker containers $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES adcd98237607 sneppets/sshd-example2 "/bin/sh -c '/usr/sb…" 6 seconds ago Up 5 seconds gracious_hertz e2c3c9b39853 sneppets/sshd-example2 "/bin/bash" 42 seconds ago Exited (0) 17 seconds ago peaceful_varahamihira
Let’s try to override default ENTRYPOINT command without mentioning –entrypoint flag with the following command /bin/bash to run bash session and see what happens.
// docker run command with default ENTRYPOINT command (Dockerfile) and without --entrypoint flag $ docker run -it sneppets/sshd-example2 /bin/bash //check container id (9ea54b0c4b66) command status it shows that you cannot override default command without --entrypoint flag $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9ea54b0c4b66 sneppets/sshd-example2 "/bin/sh -c '/usr/sb…" 7 minutes ago Up 7 minutes serene_shirley adcd98237607 sneppets/sshd-example2 "/bin/sh -c '/usr/sb…" 26 minutes ago Exited (137) 11 minutes ago gracious_hertz e2c3c9b39853 sneppets/sshd-example2 "/bin/bash" 27 minutes ago Exited (0) 27 minutes ago peaceful_varahamihira
Check the container id (9ea54b0c4b66) command status. It is evident that you cannot override default ENTRYPOINT command in Dockerfile without –entrypoint flag as it is running sshd daemon (default command) and not the bash session.
Pass more options via Command to the ENTRYPOINT
You can pass more options in case of ENTRYPOINT via Command. This is required because sometimes the user wanted to run some other command inside the container, so that you can override the default ENTRYPOINT at runtime by using a string to specify new ENTRYPOINT as shown in the example below.
$ docker run -it --entrypoint /bin/bash sneppets/sshd-example2 -c ls -l bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 83eb162915ea sneppets/sshd-example2 "/bin/bash -c ls -l" About a minute ago Exited (0) About a minute ago happy_moore
Note, Passing –entrypoint will clear out any default command that was set on the docker image.
Difference between CMD and ENTRYPOINT and Conclusion
From the above examples, it is clear that CMD defines default commands for a container. And it is best to use CMD instruction in the Dockerfile if you need a default command which users can easily override.
ENTRYPOINT makes a container locked in to a particular command. Whenever you want to define a container with a specific executable ENTRYPOINT is preferred . You cannot override an ENTRYPOINT when starting a container unless you add the –entrypoint flag. You can also pass more options or some other commands via Command to that overrriden ENTRYPOINT.
Normally you should use CMD instead of ENTRYPOINT.
Also See:
- Difference between ADD and COPY commands in a Dockerfile ?
- How to run a command in a running docker container ?
- Ping inside the docker container from host
- Docker: Error response from daemon: OCI runtime create failed: container_linux.go:349
- List the directories inside the docker container
- Add new user to the Docker container using Dockerfile
- Docker images are storage location
- Difference between Docker Images, Containers and Registries