Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
The Docker Workshop

You're reading from   The Docker Workshop Learn how to use Docker containers effectively to speed up the development process

Arrow left icon
Product type Paperback
Published in Oct 2020
Publisher Packt
ISBN-13 9781838983444
Length 792 pages
Edition 1st Edition
Tools
Concepts
Arrow right icon
Authors (5):
Arrow left icon
Engy Fouda Engy Fouda
Author Profile Icon Engy Fouda
Engy Fouda
Onur Yılmaz Onur Yılmaz
Author Profile Icon Onur Yılmaz
Onur Yılmaz
Sathsara Sarathchandra Sathsara Sarathchandra
Author Profile Icon Sathsara Sarathchandra
Sathsara Sarathchandra
Aric Renzo Aric Renzo
Author Profile Icon Aric Renzo
Aric Renzo
Vincent Sesto Vincent Sesto
Author Profile Icon Vincent Sesto
Vincent Sesto
+1 more Show less
Arrow right icon
View More author details
Toc

Table of Contents (17) Chapters Close

Preface
1. Running My First Docker Container 2. Getting Started with Dockerfiles FREE CHAPTER 3. Managing Your Docker Images 4. Multi-Stage Dockerfiles 5. Composing Environments with Docker Compose 6. Introduction to Docker Networking 7. Docker Storage 8. CI/CD Pipeline 9. Docker Swarm 10. Kubernetes 11. Docker Security 12. Best Practices 13. Monitoring Docker Metrics 14. Collecting Container Logs 15. Extending Docker with Plugins Appendix

Common Directives in Dockerfiles

As discussed in the previous section, a directive is a command that is used to create a Docker image. In this section, we will be discussing the following five Dockerfile directives:

  1. The FROM directive
  2. The LABEL directive
  3. The RUN directive
  4. The CMD directive
  5. The ENTRYPOINT directive

The FROM Directive

A Dockerfile usually starts with the FROM directive. This is used to specify the parent image of our custom Docker image. The parent image is the starting point of our custom Docker image. All the customization that we do will be applied on top of the parent image. The parent image can be an image from Docker Hub, such as Ubuntu, CentOS, Nginx, and MySQL. The FROM directive takes a valid image name and a tag as arguments. If the tag is not specified, the latest tag will be used.

A FROM directive has the following format:

FROM <image>:<tag> 

In the following FROM directive, we are using the ubuntu parent image with the 20.04 tag:

FROM ubuntu:20.04

Additionally, we can use the base image if we need to build a Docker image from scratch. The base image, known as the scratch image, is an empty image mostly used to build other parent images.

In the following FROM directive, we are using the scratch image to build our custom Docker image from scratch:

FROM scratch

Now, let's understand what a LABEL directive is in the next section.

The LABEL Directive

A LABEL is a key-value pair that can be used to add metadata to a Docker image. These labels can be used to organize the Docker images properly. An example would be to add the name of the author of the Dockerfile or the version of the Dockerfile.

A LABEL directive has the following format:

LABEL <key>=<value>

A Dockerfile can have multiple labels, adhering to the preceding key-value format:

LABEL maintainer=sathsara@mydomain.com
LABEL version=1.0
LABEL environment=dev

Or these labels can be included on a single line separated by spaces:

LABEL maintainer=sathsara@mydomain.com version=1.0 environment=dev

Labels on an existing Docker image can be viewed with the docker image inspect command.

The output should be like the following on running the docker image inspect <image>:<tag> command:

...
...
"Labels": {
    "environment": "dev",
    "maintainer": "sathsara@mydomain.com",
    "version": "1.0"
}
...
...

As shown here, the docker image inspect command will output the key-value pairs configured in the Dockerfile using the LABEL directive.

In the next section, we will learn how to execute commands during the image build time using the RUN directive.

The RUN Directive

The RUN directive is used to execute commands during the image build time. This will create a new layer on top of the existing layer, execute the specified command, and commit the results to the newly created layer. The RUN directive can be used to install the required packages, update the packages, create users and groups, and so on.

The RUN directive takes the following format:

RUN <command>

<command> specifies the shell command you want to execute as part of the image build process. A Dockerfile can have multiple RUN directives adhering to the preceding format.

In the following example, we are running two commands on top of the parent image. The apt-get update is used to update the package repositories, and apt-get install nginx -y is used to install the Nginx package:

RUN apt-get update
RUN apt-get install nginx -y

Alternatively, you can add multiple shell commands to a single RUN directive by separating them with the && symbol. In the following example, we have used the same two commands, but this time in a single RUN directive, separated by an && symbol:

RUN apt-get update && apt-get install nginx -y

Now, let's move on to the next section where we will learn about the CMD directive.

The CMD Directive

A Docker container is normally expected to run one process. A CMD directive is used to provide this default initialization command that will be executed when a container is created from the Docker image. A Dockerfile can execute only one CMD directive. If there is more than one CMD directive in the Dockerfile, Docker will execute only the last one.

The CMD directive has the following format:

CMD ["executable","param1","param2","param3", ...]

For example, use the following command to echo "Hello World" as the output of a Docker container:

CMD ["echo","Hello World"]

The preceding CMD directive will produce the following output when we run the Docker container with the docker container run <image> command (replace <image> with the name of the Docker image):

$ docker container run <image>
Hello World

However, if we send any command-line arguments with docker container run <image>, these arguments will take precedence over the CMD command that we defined. For example, if we execute the following command (replace <image> with the name of the Docker image), the default "Hello World" output defined with the CMD directive will be ignored. Instead, the container will output "Hello Docker !!!":

$ docker container run <image> echo "Hello Docker !!!"

As we discussed, both the RUN and CMD directives can be used to execute a shell command. The main difference between these two directives is that the command provided with the RUN directive will be executed during the image build process, while the command provided with the CMD directive will be executed once a container is launched from the built image.

Another notable difference between the RUN and CMD directives is that there can be multiple RUN directives in a Dockerfile, but there can be only one CMD directive (if there are multiple CMD directives, all others except the last one will be ignored).

As an example, we can use the RUN directive to install a software package during the Docker image build process and the CMD directive to start the software package once a container is launched from the built image.

In the next section, we will learn about the ENTRYPOINT directive, which provides the same functionality as the CMD directive, except for overriding.

The ENTRYPOINT Directive

Similar to the CMD directive, the ENTRYPOINT directive is also used to provide this default initialization command that will be executed when a container is created from the Docker image. The difference between the CMD directive and the ENTRYPOINT directive is that, unlike the CMD directive, we cannot override the ENTRYPOINT command using the command-line parameters sent with the docker container run command.

Note

The --entrypoint flag can be sent with the docker container run command to override the default ENTRYPOINT of the image.

The ENTRYPOINT directive has the following format:

ENTRYPOINT ["executable","param1","param2","param3", ...]

Similar to the CMD directive, the ENTRYPOINT directive also allows us to provide the default executable and the parameters. We can use the CMD directive with the ENTRYPOINT directive to provide additional arguments to the executable.

In the following example, we have used "echo" as the default command and "Hello" as the default parameter using the ENTRYPOINT directive. We have also provided "World" as the additional parameter using the CMD directive:

ENTRYPOINT ["echo","Hello"]
CMD ["World"]

The output of the echo command will differ based on how we execute the docker container run command.

If we launch the Docker image without any command-line parameters, it will output the message as Hello World:

$ docker container run <image>
Hello World

But if we launch the Docker image with additional command-line parameters (for example, Docker), the output message will be Hello Docker:

$ docker container run <image> "Docker"
Hello Docker

Before discussing the Dockerfile directives any further, let's start by creating our first Dockerfile in the next exercise.

Exercise 2.01: Creating Our First Dockerfile

In this exercise, you will create a Docker image that can print the arguments you pass to the Docker image, preceded by the text You are reading. For example, if you pass hello world, it will output You are reading hello world as the output. If no argument is provided, The Docker Workshop will be used as the standard value:

  1. Create a new directory named custom-docker-image using the mkdir command. This directory will be the context for your Docker image. Context is the directory that contains all the files needed to successfully build an image:
    $ mkdir custom-docker-image
  2. Navigate to the newly created custom-docker-image directory using the cd command as we will be creating all the files required during the build process (including the Dockerfile) within this directory:
    $ cd custom-docker-image
  3. Within the custom-docker-image directory, create a file named Dockerfile using the touch command:
    $ touch Dockerfile
  4. Now, open the Dockerfile using your favorite text editor:
    $ vim Dockerfile
  5. Add the following content to the Dockerfile, save it, and exit from the Dockerfile:
    # This is my first Docker image
    FROM ubuntu 
    LABEL maintainer=sathsara@mydomain.com 
    RUN apt-get update
    CMD ["The Docker Workshop"]
    ENTRYPOINT ["echo", "You are reading"]

    The Docker image will be based on the Ubuntu parent image. You then use the LABEL directive to provide the email address of the author of the Dockerfile. The next line executes the apt-get update command to update the package list of Debian to the latest available version. Finally, you will use the ENTRYPOINT and CMD directives to define the default executable and parameters of the container.

    We have provided echo as the default executable and You are reading as the default parameter that cannot be overridden with command-line parameters. Also, we have provided The Docker Workshop as an additional parameter that can be overridden with command-line parameters with a docker container run command.

In this exercise, we created our first Dockerfile using the common directives that we learned in the previous sections. The next step of the process is to build the Docker image from the Dockerfile. You can only run a Docker container after building the Docker image from the Dockerfile. In the next section, we are going to look at how to build a Docker image from the Dockerfile.

You have been reading a chapter from
The Docker Workshop
Published in: Oct 2020
Publisher: Packt
ISBN-13: 9781838983444
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at AU $24.99/month. Cancel anytime