Docker Building Arguments

Introduction

Sometimes, when we would like to use arguments to build our Docker image from Docker files, we could use --build-arg to build the Docker image dynamically.

In this blog post, I am going to show how we could use --build-arg to dynamically select Docker base images and the caveats of doing so.

Example

Dockerfile

We have prepared a Dockerfile build-args.Dockerfile. The content of the Dockerfile is as follows.

1
2
3
4
5
6
7
8
9
ARG _UBUNTU_VERSION=18.04

FROM ubuntu:${_UBUNTU_VERSION}

ARG _CUDA_VERSION=10.0

RUN echo ${_CUDA_VERSION}
RUN echo ${_UBUNTU_VERSION}
RUN cat /etc/lsb-release

With ARG, we have prepared two arguments _UBUNTU_VERSION and _CUDA_VERSION with their default values set to 18.04 and 10.0, respectively.

Building Without Custom Arguments

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ docker build -f build-args.Dockerfile --no-cache --tag ubuntu:custom .
Sending build context to Docker daemon 2.048kB
Step 1/6 : ARG _UBUNTU_VERSION=18.04
Step 2/6 : FROM ubuntu:${_UBUNTU_VERSION}
---> 4c108a37151f
Step 3/6 : ARG _CUDA_VERSION=10.0
---> Running in e8ea62c039fb
Removing intermediate container e8ea62c039fb
---> 9862cc2743d6
Step 4/6 : RUN echo ${_CUDA_VERSION}
---> Running in b89f1788f822
10.0
Removing intermediate container b89f1788f822
---> 31bd45aab0c4
Step 5/6 : RUN echo ${_UBUNTU_VERSION}
---> Running in 640da900d0e5

Removing intermediate container 640da900d0e5
---> ea9022c7619b
Step 6/6 : RUN cat /etc/lsb-release
---> Running in 352e5ba34e1d
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS"
Removing intermediate container 352e5ba34e1d
---> 15df659b939f
Successfully built 15df659b939f
Successfully tagged ubuntu:custom

We could see that there are actually two scopes for the arguments. _UBUNTU_VERSION would not be available after the base image was built. But _UBUNTU_VERSION was definitely available before the base image was built because the image was “Ubuntu 18.04.2 LTS” which was exactly the same as our default value.

Building With Custom Arguments

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ docker build -f build-args.Dockerfile --build-arg _CUDA_VERSION=10.2 --build-arg _UBUNTU_VERSION=16.04 --no-cache --tag ubuntu:custom .
Sending build context to Docker daemon 2.048kB
Step 1/6 : ARG _UBUNTU_VERSION=18.04
Step 2/6 : FROM ubuntu:${_UBUNTU_VERSION}
---> c6a43cd4801e
Step 3/6 : ARG _CUDA_VERSION=10.0
---> Running in b93c73bb14b1
Removing intermediate container b93c73bb14b1
---> ca1e8b65bf5b
Step 4/6 : RUN echo ${_CUDA_VERSION}
---> Running in 9546a32abbd4
10.2
Removing intermediate container 9546a32abbd4
---> 529e4f08ae49
Step 5/6 : RUN echo ${_UBUNTU_VERSION}
---> Running in 4353a17ec826

Removing intermediate container 4353a17ec826
---> a84f1b8dc62a
Step 6/6 : RUN cat /etc/lsb-release
---> Running in ac5adeb44920
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS"
Removing intermediate container ac5adeb44920
---> 637557dc9ecd
Successfully built 637557dc9ecd
Successfully tagged ubuntu:custom

With --build-arg provided, we could see that the default argument values had been overwritten. However, _UBUNTU_VERSION, which was defined before the base image was built, was still not available after the base image was built.

Conclusions

Be aware of the scope of Docker building arguments.

Author

Lei Mao

Posted on

12-20-2019

Updated on

12-20-2019

Licensed under


Comments