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