Reputation: 1980
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
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
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
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
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
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