docker tutorials

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
[email protected]:/# 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:

References:

Leave a Reply

avatar
  Subscribe  
Notify of