Docker – The Docker image build command

How to create virtual machines with VirtualBox

OK, so the image build command is not a Dockerfile instruction. Instead, it is the docker command that is used to turn your Dockerfile into a docker image. The Docker image build command sends the docker build context, including the Dockerfile, to the docker daemon, which parses the Dockerfile and builds the image layer by layer. We will discuss the build context shortly, but for now, consider it to be everything that is needed to build the Docker image based on the content found in the Dockerfile. The build command syntax is as follows:

# Docker image build command syntax
Usage: docker image build [OPTIONS] PATH | URL | -

There are many options for the image build command. We will not be covering all of the options now, but let’s take a look at a few of the most common:

# Common options used with the image build command
--rm         Remove intermediate containers after a successful build
--build-arg  Set build-time variables
--tag        Name and optionally a tag in the 'name:tag' format
--file       Name of the Dockerfile (Default is 'PATH/Dockerfile')

The Docker daemon builds the image by creating a new image from each command in the Dockerfile. Each new image is built upon the previous. Using the optional --rm parameter will instruct the daemon to delete all the intermediate images when the build completes successfully. Using this will slow the build process when you rebuild a successfully built image, but will keep the local image cache cleaner.

We have already talked about build args when we covered the ARG instruction. Remember that the --build-arg option is how you provide a value to the ARG instruction in the Dockerfile.

The --tag option allows you to give your images a more human-readable name and version. We have seen this option used in several of the earlier examples as well. 

The --file option allows you to use a filename other than Dockerfile, and to keep the Dockerfile in a path other than the build context folder.

Here are some image build commands for reference:

# build command samples
docker image build --rm --build-arg username=35 --tag arg-demo:2.0 .
docker image build --rm --tag user-demo:1.0 .
docker image build --rm --tag workdir-demo:1.0 .

You will notice the trailing . in each of the preceding examples. This period is indicating that the current working directory is the root of the build context for the image build.

Parser Directives

Parser Directives are a special subset of optional comment lines in the Dockerfile. Any parser directives must occur before the first normal comment line. They must also precede any blank lines or other build instructions, including the FROM instruction. Basically, all parser directives must be at the very top of the Dockerfile. By the way, if you haven’t figured it out yet, you can create a normal comment line in a Dockerfile by starting that line with a # character. The syntax for a parser directive is as follows:

# directive=value
# The line above shows the syntax for a parser directive

So, what can you do with a parser directive? Well right now, the only one supported is escape. The escape parser directive is used to change what character is used to indicate that the next character in the instruction is to be treated as a character and not as the special character it represents. The default value if no parser directive is used is \. You have seen this used in several examples throughout this chapter to escape the newline character, allowing for instructions to be continued onto the next line in the Dockerfile. If it is necessary to use a different escape character, you can use the escape parser directive to handle that. You can set the escape character to one of two choices:

# escape=\ (backslash)
# escape=` (backtick)

One example where you might want to change the character used as the escape character is when you are creating a Dockerfile on Windows systems. As you know, the \ is used to distinguish folder levels in path strings, such as c:\windows\system32
. Switching to the backtick for the escape character will avoid needing to escape such strings as this: c:\\windows\\system32\\drivers.

The build context

The build context is everything that gets sent to the Docker daemon when using the build image command. This includes the Dockerfile and the contents of the current working directory when the build command is issued, including all subdirectories that the current working directory may contain. It is possible to have the Dockerfile in a directory other than the current working directory by using a -f or --file option, but the Dockerfile still gets sent with the build context. Using the .dockerignore file, you can exclude files and folders from the build context when it gets sent to the Docker daemon.

When building Docker images, it is very important to keep the build context as small as possible. This is because the entire build context is sent to the Docker daemon for building the image. If you have unnecessary files and folders in the build context, then it will slow the build process, and depending on the contents of the Dockerfile, can result in bloated images. This is such an important consideration, that every image build command displays the size of the build context as the first line of the command’s output. It looks like this:

The build context becomes the filesystem root for the commands in the Dockerfile. For example, consider using the following COPY instruction:

# build context Dockerfile for Docker Quick Start guide
FROM scratch
COPY hello /
CMD ["/hello"]

This tells the Docker daemon to copy the hello file from the root of the build context into the root of the container image.

If the command completes successfully, the image ID will be displayed, and if a --tag option is provided, the new tag and version will be shown as well:

One of the keys to keeping the build context small is the use of a .dockerignore file.

The .dockerignore file

If you are familiar with using .gitignore files, then you will already have a basic understanding of the purpose for the .dockerignore file. The .dockerignore file is used to exclude files that you do not want to be included with the build context during a docker image build. Using it helps to prevent sensitive and other unwanted files from being included in the build context, and potentially in the docker image. It is an excellent tool to help keep your Docker images small.

The .dockerignore file needs to be in the root folder of the build context. Like a .gitignore file, it uses a newline-separated list of patterns. Comments in the .dockerignore file are denoted by a # as the first character of a line. You can override a pattern by including an exception line. An exception line is denoted with a ! as the first character of the line. All other lines are considered patterns to use to exclude files and/or folders.

Line order in the .dockerignore file is significant. Matching patterns of lines later in the file will override matching lines earlier in the file. If you add a pattern that matches the .dockerignore file or the Dockerfile file, they will still be sent to the docker daemon with the build context, but they will not be available to any ADD or COPY instructions, and therefore cannot end up in the resulting image. Here is an example:

# Example of a .dockerignore file
# Exclude unwanted files

Comments are closed.