405

According to the documentation, it's possible to define multiple args for the flag --build-arg, but I can't find out how. I tried the following:

docker build -t essearch/ess-elasticsearch:1.7.6 --build-arg number_of_shards=5 number_of_replicas=2 --no-cache .

=> This returns an error.

I also tried:

docker build -t essearch/ess-elasticsearch:1.7.6 --build-arg number_of_shards=5,number_of_replicas=2 --no-cache .

=> This sets one variable, number_of_shards, to the value "5,number_of_replicas=2"

Any idea how I can define multiple arguments?

lospejos
  • 1,976
  • 3
  • 19
  • 35
Emilien Brigand
  • 9,943
  • 8
  • 32
  • 37

6 Answers6

803

Use --build-arg with each argument.

If you are passing two argument then add --build-arg with each argument like:

docker build \
-t essearch/ess-elasticsearch:1.7.6 \
--build-arg number_of_shards=5 \
--build-arg number_of_replicas=2 \
--no-cache .
Flynn Hou
  • 429
  • 1
  • 6
  • 18
pl_rock
  • 14,054
  • 3
  • 30
  • 33
  • 116
    Thanks for clearing this up. The `--help` on this is especially misleading: `--build-arg list`. It's not a list! – cowlinator Jan 13 '18 at 03:23
  • 6
    Maybe it's deprecated... I keep receiving `"docker build" requires exactly 1 argument.` – Sandburg Mar 24 '22 at 15:37
  • 2
    The `exactly 1 argument` that's required is the directory (the `.` at the end of this example). – Jason Orendorff Oct 25 '22 at 21:31
  • 1
    For multiline `--build-arg`: https://stackoverflow.com/a/50299998/432903 – prayagupa Dec 08 '22 at 20:50
  • If that is the case then the documentation seems wrong. According to "docker build --help" the --build_arg is described as a list. it isn't really specifying a list if I have to repeat the entire argument over and over with a single value each time. – shawn1874 May 21 '23 at 23:02
181

The above answer by pl_rock is correct, the only thing I would add is to expect the ARG inside the Dockerfile if not you won't have access to it. So if you are doing

docker build -t essearch/ess-elasticsearch:1.7.6 --build-arg number_of_shards=5 --build-arg number_of_replicas=2 --no-cache .

Then inside the Dockerfile you should add

ARG number_of_replicas
ARG number_of_shards

I was running into this problem, so I hope I help someone (myself) in the future.

Javier Perez
  • 1,855
  • 1
  • 11
  • 8
  • 19
    you helped me also, so thanks. Let me add only that `ARGS` must be declared after `FROM` – Edoardo Nov 13 '18 at 16:54
  • 19
    Wow thanks! Using `ARG` is not even mentioned in https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables---build-arg and `--build-arg` was useless for me without `ARG` – HeyWatchThis Dec 08 '18 at 20:00
  • 3
    Also useless for me before FROM... :-/ – ibz Nov 25 '21 at 21:19
  • Note, if you plan to utilize the env variables once your container has started you use the same patters except your docker file will use ENV instead of ARG https://stackoverflow.com/questions/39597925/how-do-i-set-environment-variables-during-the-build-in-docker – user6866797 Nov 13 '22 at 00:09
  • Lost way to many time with this. FYI, here is the documentation which states that ARG must be used after FROM (well it can for all step before FROM if I read correctly) – Greg7000 Dec 21 '22 at 13:33
70

If you want to use environment variable during build. Lets say setting username and password.

username= Ubuntu
password= swed24sw

Dockerfile

FROM ubuntu:16.04
ARG SMB_PASS
ARG SMB_USER
# Creates a new User
RUN useradd -ms /bin/bash $SMB_USER
# Enters the password twice.
RUN echo "$SMB_PASS\n$SMB_PASS" | smbpasswd -a $SMB_USER

Terminal Command

docker build --build-arg SMB_PASS=swed24sw --build-arg SMB_USER=Ubuntu . -t IMAGE_TAG

Fakabbir Amin
  • 989
  • 7
  • 16
  • 22
    Beware that this leaves the secret values visible in the docker image using the `docker history` command. – Gary Jun 27 '19 at 18:22
19

It's a shame that we need multiple ARG too, it results in multiple layers and slows down the build because of that, and for anyone also wondering that, currently there is no way to set multiple ARGs per one line.

Vlad Kolbaia
  • 267
  • 4
  • 11
  • 2
    this can be combined with [multi stage builds](https://docs.docker.com/develop/develop-images/multistage-build/) to reduce layers on the final built image – deepakkt Dec 01 '20 at 13:19
  • This doesn't answer the question of how to set multiple build args. With buildkit you won't see separate steps being performed, and with the classic build, those additional steps are not filesystem layers. – BMitch Apr 09 '21 at 12:08
  • This answer can be misleading. What is true is that there is no way to set multiple arguments in one line. But, multiple args are definitely supported. – Willem Nov 03 '21 at 09:17
  • 1
    Clarified the statement – Vlad Kolbaia Nov 04 '21 at 13:05
  • ARG instruction does not create a new layer in modern Docker. https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#minimize-the-number-of-layers – Dzenly Mar 15 '22 at 18:39
15

In case you want to pass automatically build arguments from a specific file, you can do it this way :

docker build  $(cat .my-env-file-name | while read line; do out+="--build-arg $line"; done; echo $out; out="") .
Clément Faure
  • 151
  • 1
  • 4
  • i cant figure out why but if you put quotes around the command substitution $() causes docker build to break. it loses the '=value' part. this was driving me nuts for a while here! any idea why? – vampiire Mar 03 '22 at 22:57
  • get_build_args() { for build_arg in "${BUILD_ARGS[@]}"; do out+="--build-arg $build_arg " done echo -n "$out" } i wrote this assuming BUILD_ARGS is an array with elements ARG_NAME=VALUE. it works well and when i echo the output its all there. however when substituted in to docker build if i put quotes around it then it breaks. really confused – vampiire Mar 03 '22 at 22:59
  • example: build_args=\`get_build_args\` echo $build_args echo "$build_args" docker build $build_args . docker build "$build_args" . – vampiire Mar 03 '22 at 23:00
6

A way to pass in build arguments from a file using xargs is as follows:

cat .MY_ENV_FILE | xargs printf -- '--build-arg %s\n' | xargs docker build -t MY_TAG .
Ngstigator
  • 89
  • 1
  • 5
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/31050917) – mbuechmann Feb 18 '22 at 09:37