Muhammad Abdul Raheem
Muhammad Abdul Raheem

Reputation: 1980

Dockerfile define multiple ARG arguments in a single line

Right now I am defining ARGs in my Dockerfile like this:

ARG CDN_ENDPOINT
ARG AWS_S3_BUCKET

Is there a way to define them in a single line similar to ENV to avoid creating extra layers in docker image like this:

ENV CDN_ENDPOINT=endpoint \
    AWS_S3_BUCKET=bucket

Upvotes: 47

Views: 41129

Answers (5)

Muhammad Abdul Raheem
Muhammad Abdul Raheem

Reputation: 1980

YES, After release 1.2.0

Previously it was not possible and it threw the following error

ARG requires exactly one argument definition

But after release 1.2.0 it is now possible to define ARG like following

ARG CDN_ENDPOINT \
AWS_S3_BUCKET

Upvotes: 74

agoncal
agoncal

Reputation: 11

Complementing previous answers with a possible outcome for ARG instruction:

If for some reason you pretend to reuse those ARGs after FROM action, you can also use a single line and without need to re-declare default value.

ARG PARENT_IMAGE=rocky8
ARG PARENT_TAG=8.9
ARG REGISTRY=docker.io
FROM ${REGISTRY}${PARENT_IMAGE}:${PARENT_TAG}

ARG PARENT_IMAGE PARENT_TAG

#e.g. for a ARG re-usage, declaring a label:
LABEL org.baseimage="${PARENT_IMAGE}:${PARENT_VERSION}"

https://github.com/moby/moby/issues/34129#issuecomment-445540809

Upvotes: 1

adamg
adamg

Reputation: 21

There is a way to write a one-liner, but it seems to require specifying default values, like so:

ARG CDN_ENDPOINT=endpoint \
    AWS_S3_BUCKET=bucket

One could then override these values by specifying build arguments in the docker build command:

docker build -t <name:tag> --build-arg CDN_ENDPOINT=overriddenValue1 --build-arg AWS_S3_BUCKET=overriddenValue2 <context>

To test layering, I created two Dockerfiles:

Dockerfile-1:

FROM alpine

ARG CDN_ENDPOINT=endpoint \
    AWS_S3_BUCKET=bucket

Dockerfile-2:

FROM alpine

ARG CDN_ENDPOINT=endpoint
ARG AWS_S3_BUCKET=bucket

After building each and running the command docker history <image-id>, here were the results showing the layers. It does seems like image-1 kept the ARG one-liner to one layer while image-2 used two layers:

image-1:

IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
ca690c8c2cfc   3 months ago   ARG CDN_ENDPOINT=endpoint AWS_S3_BUCKET=buck…   0B        buildkit.dockerfile.v0
<missing>      3 months ago   /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>      3 months ago   /bin/sh -c #(nop) ADD file:2a949686d9886ac7c…   5.54MB

image-2:

IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
e4bee80eb809   3 months ago   ARG AWS_S3_BUCKET=bucket                        0B        buildkit.dockerfile.v0
<missing>      3 months ago   ARG CDN_ENDPOINT=endpoint                       0B        buildkit.dockerfile.v0
<missing>      3 months ago   /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>      3 months ago   /bin/sh -c #(nop) ADD file:2a949686d9886ac7c…   5.54MB

Upvotes: 2

Ren&#233; Lazo
Ren&#233; Lazo

Reputation: 671

To achieve what you want you have to do this:

in your Dockerfile define the ARG variables you need with a default value (so, in case you don't pass it it can still work):

ARG P_TAG=8-jdk
FROM openjdk:${P_TAG}

ARG P_VERSION="1.22.2-stable"

ENV TAG=${P_TAG}
ENV VERSION=${P_VERSION}

RUN echo TAG=${TAG}
RUN echo VERSION=${VERSION}

Then your build line should go like this:

docker build --build-arg P_TAG=11-jdk --build-arg P_VERSION=2.0.4-stable

You need to be sure that your dockerfile contains as ARG all the variables you need to pass.

Upvotes: 7

Shadja Chaudhari
Shadja Chaudhari

Reputation: 303

On a different note, ARG does not go in the build image. So may be, one should not worry about the layers caused by ARG.

Upvotes: 17

Related Questions