CMD and ENTRYPOINT

Posted on Apr 03, 2019   ∣  4 min read  ∣  Docker

CMD and ENTRYPOINT

Container entry doors


Objectives

In this lesson, we will learn about two important Dockerfile commands:

CMD and ENTRYPOINT.

These commands allow us to set the default command to run in a container.


Defining a default command

When people run our container, we want to greet them with a nice hello message, and using a custom font.

For that, we will execute:

figlet -f script hello

Adding CMD to our Dockerfile

Our new Dockerfile will look like this:

FROM ubuntu
RUN apt-get update
RUN ["apt-get", "install", "figlet"]
CMD figlet -f script hello

Build and test our image

Let’s build it:

$ docker build -t figlet .
...
Successfully built 042dff3b4a8d
Successfully tagged figlet:latest

And run it:

$ docker run figlet
 _          _   _       
| |        | | | |      
| |     _  | | | |  __  
|/ \   |/  |/  |/  /  \_
|   |_/|__/|__/|__/\__/ 

Overriding CMD

If we want to get a shell into our container (instead of running figlet), we just have to specify a different program to run:

$ docker run -it figlet bash
root@7ac86a641116:/# 

Using ENTRYPOINT

We want to be able to specify a different message on the command line, while retaining figlet and some default parameters.

In other words, we would like to be able to do this:

$ docker run figlet salut
           _            
          | |           
 ,   __,  | |       _|_ 
/ \_/  |  |/  |   |  |  
 \/ \_/|_/|__/ \_/|_/|_/

We will use the ENTRYPOINT verb in Dockerfile.


Adding ENTRYPOINT to our Dockerfile

Our new Dockerfile will look like this:

FROM ubuntu
RUN apt-get update
RUN ["apt-get", "install", "figlet"]
ENTRYPOINT ["figlet", "-f", "script"]

Why did we use JSON syntax for our ENTRYPOINT?


Implications of JSON vs string syntax

What if we used ENTRYPOINT with string syntax?

$ docker run figlet salut

This would run the following command in the figlet image:

sh -c "figlet -f script" salut

Build and test our image

Let’s build it:

$ docker build -t figlet .
...
Successfully built 36f588918d73
Successfully tagged figlet:latest

And run it:

$ docker run figlet salut
           _            
          | |           
 ,   __,  | |       _|_ 
/ \_/  |  |/  |   |  |  
 \/ \_/|_/|__/ \_/|_/|_/

Using CMD and ENTRYPOINT together

What if we want to define a default message for our container?

Then we will use ENTRYPOINT and CMD together.


CMD and ENTRYPOINT together

Our new Dockerfile will look like this:

FROM ubuntu
RUN apt-get update
RUN ["apt-get", "install", "figlet"]
ENTRYPOINT ["figlet", "-f", "script"]
CMD ["hello world"]

Build and test our image

Let’s build it:

$ docker build -t figlet .
...
Successfully built 6e0b6a048a07
Successfully tagged figlet:latest

Run it without parameters:

$ docker run figlet
 _          _   _                             _        
| |        | | | |                           | |    |  
| |     _  | | | |  __             __   ,_   | |  __|  
|/ \   |/  |/  |/  /  \_  |  |  |_/  \_/  |  |/  /  |  
|   |_/|__/|__/|__/\__/    \/ \/  \__/    |_/|__/\_/|_/

Overriding the image default parameters

Now let’s pass extra arguments to the image.

$ docker run figlet hola mundo
 _           _                                               
| |         | |                                      |       
| |     __  | |  __,     _  _  _           _  _    __|   __  
|/ \   /  \_|/  /  |    / |/ |/ |  |   |  / |/ |  /  |  /  \_
|   |_/\__/ |__/\_/|_/    |  |  |_/ \_/|_/  |  |_/\_/|_/\__/ 

We overrode CMD but still used ENTRYPOINT.


Overriding ENTRYPOINT

What if we want to run a shell in our container?

We cannot just do docker run figlet bash because that would just tell figlet to display the word “bash.”

We use the --entrypoint parameter:

$ docker run -it --entrypoint bash figlet
root@6027e44e2955:/#