Build image#

Here is a look at the docker build command, its features and options.

Build context#

Read more on the corresponding page in the official documentation and specific page in this site.

The build command requires one argument: the path to the build folder. This argument specifies which folder will be used as the working directory for the build process. All relative paths will be considered relative to this specified path.


As an example, consider the configuration created in the following cell.

mkdir build_path
cat << EOF > build_path/dockerfile
FROM alpine
COPY message message
CMD ["cat", "message"]
EOF

echo "I'm external message" > build_path/message

mkdir build_path/folder
echo "I'm nested message" > build_path/folder/message

Here is a Dockerfile that modifies the alpine image to print the message file from the build folder. There are two message files located in different folders.

For better understanding, here is the file tree:

tree build_path
build_path
├── dockerfile
├── folder
│   └── message
└── message

1 directory, 3 files

Here is an image that uses build_path as the build folder. Container using this image prints I'm external message.

docker build \
    -t external_image \
    -f ./build_path/dockerfile \
    ./build_path &> /dev/null
docker run --rm external_image
I'm external message

Note In the examples, the -f option is used to specify the path to the docker file, which is generally not the same as the building path.

Exactly the same folder, but using a different build folder - prints a different message.

docker build \
    -t nested_image \
    -f ./build_path/dockerfile \
    ./build_path/folder &> /dev/null
docker run --rm nested_image
I'm nested message

Getting rid of files and images we created for examples.

rm -r build_path
docker rmi external_image nested_image
Untagged: external_image:latest
Deleted: sha256:4d888a7322bda81b44c934cf6079a5637086150f86490c59862d3b6c1fa2804f
Untagged: nested_image:latest

Image name (-t)#

You can set the image name (tag) using the -t <image name> option.


The following cell shows the process of creating a docker image named super_duper_puper.

mkdir image_name
cat << EOF > image_name/dockerfile
FROM alpine
EOF

docker build -t super_duper_puper ./image_name &> /dev/null
docker images | grep super_duper_puper

docker rmi super_duper_puper &> /dev/null
rm -r image_name
super_duper_puper                                                   latest           64a95b915f9e   3 weeks ago     7.8MB

Select dockerfile (-f)#

You can pass the filepath to the docker image in the -f option. If your file specifying the build directive has a name different from dockerfile, you will need to specify the actual name as the -f parameter.


Following cell defiens docker file with name python_apline

mkdir select_dockerfile
cat << EOF > select_dockerfile/python_alpine
FROM alpine
RUN apk add python3
EOF

If you’re just trying to build it, specify the path to the folder with the dockerfile.

docker build ./select_dockerfile
?25l[+] Building 0.0s (0/1)                                          docker:default
?25h?25l[+] Building 0.0s (1/1) FINISHED                                 docker:default
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 2B                                         0.0s
?25hERROR: failed to solve: failed to read dockerfile: open Dockerfile: no such file or directory

You have to specify path to the docker file in -f option, only in such case image will build properly.

docker build \
    -t temp_image \
    -f ./select_dockerfile/python_alpine . &> /dev/null
docker images | grep temp_image
temp_image                    latest        d4d220b7f3bf   20 minutes ago   50.7MB
docker rmi temp_image &> /dev/null
rm -r ./select_dockerfile

Ignore files#

You can ignore some files with a .dockerignore file. Any files specified in this file will be ignored by Docker when building the image. “Ignoring” a file means not adding it to the build context.

For more details, see specific page about Docker ignore files.


We’ll show you how it works by removing the build context of the specific docker image. So the following cell creates a random files tree and puts secret_file in it, which we want to ignore. We’ll use it as the build context.

mkdir example_tree

# Function to create a random string
random_string() {
    cat /dev/urandom | tr -cd 'a-z0-9' | head -c 8
}

OBJECTS_NUMBER=5
curr_dir="example_tree"

for ((i=0; i<OBJECTS_NUMBER; i++)) do
    object_name="$curr_dir/$(random_string)"

    if [ $(($RANDOM % 4)) -eq 0 ]; then
        mkdir $object_name
        curr_dir=$object_name
    else
        echo $(fortune) > $object_name
    fi
done

echo $(fortune) > example_tree/secret_file

tree example_tree
example_tree
├── la7kwqku
│   ├── i2lrkj2a
│   ├── lhveaor5
│   ├── ln4nkv06
│   └── mqio09fo
└── secret_file

3 directories, 4 files

Here is files that specify behaviour of the docker build command:

  • dockerignore in the context folder, just contains the name of the file we want to exclude from the context.

  • dockerfile is a special docker file that will store whole context in the /context folder.

cat << EOF > ./example_tree/.dockerignore
secret_file
EOF

cat << EOF > dockerfile
FROM alpine
COPY . /context/
EOF

Now let’s build a container, run image and check the contents of the context folder.

docker build \
    -t docker_ignore_example \
    -f ./dockerfile \
    ./example_tree &> /dev/null
docker run --rm docker_ignore_example tree /context
/context
└── la7kwqku
    ├── i2lrkj2a
    ├── lhveaor5
    ├── ln4nkv06
    └── mqio09fo

2 directories, 3 files

As you can see, there is no secret_file here.

Don’t foreget to clean the environment after all:

rm -r example_tree dockerfile
docker rmi docker_ignore_example
Untagged: docker_ignore_example:latest
Deleted: sha256:e1110f1a6e9c3b4ce1a36a88e3da5d8f95cf80f1950eecdb9246e3db749242b5
Deleted: sha256:fb4226cb869208fa9047929c626b707e3835e4b4693d00ca36c3898202351dd4

Echo information#

Sometimes it can be useful to see some information on the standard output for debugging/research purposes. You can add the RUN <command> directive to your dockerfile, but in general it wouldn’t print the output, you need to use the --no-cache options to guarantee that the output of the command will be available in the standard output.


The following cell defines dockerfile which uses RUN whoami so that the some stage of the build it has to show the output of the whoami command.

cat << EOF > /tmp/echo_info
FROM alpine
RUN whoami
EOF

Now the build the image based on this dockerfile, right after cleaning the build cache.

docker builder prune -af &> /dev/null
docker build -t echo_info -f /tmp/echo_info . 2>&1 | grep -A 1 "whoami"
#5 [2/2] RUN whoami
#5 0.109 root

As a result, there is an output for the command, but it only for the first time, all other times it simply won’t show the output of the command because it wasn’t executed due to it being cached.

docker build -t echo_info -f /tmp/echo_info . 2>&1 | grep -A 1 "whoami"
#5 [2/2] RUN whoami
#5 CACHED

But with --no-cache option you easily can return the output of the command.

docker build -t echo_info --no-cache -f /tmp/echo_info . 2>&1 | grep -A 1 "whoami"
#5 [2/2] RUN whoami
#5 0.121 root