472

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?

7 Answers 7

936
+500

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 .
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for clearing this up. The --help on this is especially misleading: --build-arg list. It's not a list!
Maybe it's deprecated... I keep receiving "docker build" requires exactly 1 argument.
The exactly 1 argument that's required is the directory (the . at the end of this example).
For multiline --build-arg: stackoverflow.com/a/50299998/432903
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.
|
204

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.

6 Comments

you helped me also, so thanks. Let me add only that ARGS must be declared after FROM
Wow thanks! Using ARG is not even mentioned in docs.docker.com/engine/reference/commandline/build/… and --build-arg was useless for me without ARG
Also useless for me before FROM... :-/
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 stackoverflow.com/questions/39597925/…
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)
|
74

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

1 Comment

Beware that this leaves the secret values visible in the docker image using the docker history command.
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.

5 Comments

this can be combined with multi stage builds to reduce layers on the final built image
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.
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.
Clarified the statement
ARG instruction does not create a new layer in modern Docker. docs.docker.com/develop/develop-images/…
16

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="") .

3 Comments

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?
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
example: build_args=`get_build_args` echo $build_args echo "$build_args" docker build $build_args . docker build "$build_args" .
8

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 .

2 Comments

This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review
my problem with this is that your second xargs is going to run for each of first -> docker build multiple times with one --build-arg read from the file instead of having multiple --build-arg added to the same docker build.
2

thanks to pl_rock. This syntax worked for me in my gitlab pipeline (running alpine linux):

  script:
    - echo "attempting a multi-line build"
    - |
      docker build \
      --build-arg USER=${USER} \
      --build-arg PASSWORD=${PASSWORD} \
      -t ${IMAGE} \
      -f Dockerfile .
    - echo "Great Success"

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.