CMD
and ENTRYPOINT
- Objectives
- Defining a default command
- Adding
CMD
to our Dockerfile - Build and test our image
- Overriding
CMD
- Using
ENTRYPOINT
- Adding
ENTRYPOINT
to our Dockerfile - Implications of JSON vs string syntax
- Build and test our image
- Using
CMD
andENTRYPOINT
together CMD
andENTRYPOINT
together- Build and test our image
- Overriding the image default parameters
- Overriding
ENTRYPOINT
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
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:/#
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 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.
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 .
...
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:/#