CMD and ENTRYPOINT¶
See also
Contents
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
-f script tells figlet to use a fancy font.
hello is the message that we want it to display.
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
CMD defines a default command to run when none is given.
It can appear at any point in the file.
Each CMD will replace and override the previous one.
As a result, while you can have multiple CMD lines, it is useless.
Build and test our image¶
docker build -t figlet .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM ubuntu
---> 452a96d81c30
Step 2/4 : RUN apt-get update
---> Using cache
---> 01e04143b340
Step 3/4 : RUN ["apt-get", "install", "figlet"]
---> Using cache
---> ba8d944adee0
Step 4/4 : CMD figlet -f script hello
---> Running in 9ab6d5965c4c
Removing intermediate container 9ab6d5965c4c
---> d06ea4383cc6
Successfully built d06ea4383cc6
Successfully tagged figlet:latest
# 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
We specified bash.
It replaced the value of CMD.
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"]
ENTRYPOINT defines a base command (and its parameters) for the container.
The command line arguments are appended to those parameters.
Like CMD, ENTRYPOINT can appear anywhere, and replaces the previous value.
Why did we use JSON syntax for our ENTRYPOINT ?
Implications of JSON vs string syntax¶
When CMD or ENTRYPOINT use string syntax, they get wrapped in sh -c.
To avoid this wrapping, we can use JSON 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 cede00171081
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.
ENTRYPOINT will define the base command for our container.
CMD will define the default parameter(s) for this command.
They both have to use JSON syntax.
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"]
ENTRYPOINT defines a base command (and its parameters) for the container.
If we don’t specify extra command-line arguments when starting the container, the value of CMD is appended.
Otherwise, our extra command-line arguments are used instead of CMD.
Build and test our image¶
Let’s build it:
# docker build -t figlet .
Sending build context to Docker daemon 2.048kB
Step 1/5 : FROM ubuntu
---> 452a96d81c30
Step 2/5 : RUN apt-get update
---> Using cache
---> 01e04143b340
Step 3/5 : RUN ["apt-get", "install", "figlet"]
---> Using cache
---> ba8d944adee0
Step 4/5 : ENTRYPOINT ["figlet", "-f", "script"]
---> Using cache
---> cede00171081
Step 5/5 : CMD ["hello world"]
---> Running in 5019ef053005
Removing intermediate container 5019ef053005
---> 848a294a8347
Successfully built 848a294a8347
Successfully tagged figlet:latest
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