Docker currently only allows to pass multiple build arguments via multiple --build-argument
options to the docker build
command. So, if we have, for example, a .env
file containing build arguments (like versions of software we need to install) in our Dockerfile
FROM ubuntu:22.04
ARG VERSION_FOO
ARG VERSION_BAR
ARG VERSION_BAZ
RUN echo "VERSION_FOO=$VERSION_FOO, VERSION_BAR=$VERSION_BAR, VERSION_BAZ=$VERSION_BAZ"
then we will have to run docker build
like so:
docker build --build-arg VERSION_FOO=0.0.1 --build-arg VERSION_BAR=1.0.1 VERSION_BAZ=3.14.0 .
To do this dynamically, we may do a little BASH magic to construct the build args substring from the .env
file. Assuming .env
contains
VERSION_FOO=0.0.1
VERSION_BAR=1.0.1
VERSION_BAZ=3.14.0
we may read the variable assignments in the .env
file into an array and then use this array in our docker build
call:
build_args=()
while IFS= read -r line; do
build_args+="--build-arg=$line"
done < .env
docker build -t test ${build_args[@]} .
Note that the =
after --build-arg
is required (at least in Docker 26.1.2 which is the version I’m running at the time of writing), because docker build
will otherwise fail with a syntax error:
unknown flag: —build-arg VERSION_FOO
We also use an array to store the build arguments and use the interpolation syntax for getting
all array elements (${build_args[@]}
) for the same reason.
We could use multiple .env
sources, e.g. by using a sub shell with cat
: e.g.
build_args=()
while IFS= read -r line; do
. build_args+="--build-arg=$line"
done <<(cat .env1 .env2)
docker build -t test ${build_args[@]} .