Dockerfile 中 ARG 的使用与其作用域(Scope)探究

使用 ARG​ 可以有效的复用 Dockerfile。每次镜像更新,只需要动态的在 build 命令中传入新的参数值即可。

0x01 结论

在第一个FROM​ 之前的所有 ARG , 在所有 FROM​ 中生效, 仅在 FROM 中生效在FROM​ 后的 ARG​, 仅在当前 FROM 作用域生效。即尽在当前 阶段 (stage)对照组解析

在随后的 Dockerfile 中, 只定义了一个变量 image​ , 并在 FROM 和 stage

对照组1:stage1​ 和 stage11​ 均在 FROM​ 中使用了变量 $image​: **作用域在所有 FROM 中

成功拉取FROM $image 并完成 layer 构建

但是在RUN 中无法正确输出结果,即 image 的值 alpine:3.12

对照组2:stage1​ vs stage2: 作用域在 FROM stage 内部

在 stage2​ 的作用域中声明了 ARG image,且能正确输出结果。

对照组3: stage2​ vs stage21​: 作用域仅在当前 FROM stage 内部

虽然 stage2​ 在 stage21​ 上方且声明了 ARG image​, 但 stage21 仍然不能不能正确输出结果。

0x02 实验过程

创建 Dockerfile 如下:

复制

## 在第一个 FROM 之前的所有 ARG , 在所有 FROM 中生效, 仅在 FROM

中生效

ARG image

FROM $image as

stage1

RUN echo "stage1 -> base from image is : $image " # result: stage1 -> base from image is :FROM $image as

stage11

RUN echo "stage11 -> base from image is : $image " # result: stage11 -> base from image is :FROM alpine:3.12 as

stage2

## 在 FROM 后的 ARG, 仅在当前 FROM 作用域生效。即尽在当前 阶段 (stage)

生效

ARG image

RUN echo "stage2 -> base from image is : $image " # stage2 -> base from image is : alpine:3.12FROM alpine:3.12 as

stage21

RUN echo "stage21 -> base from image is : $image " # stage21 -> base from image is :1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.

执行docker build 命令:

复制# docker build --build-arg image=alpine:3.12 --no-cache .1.

build 结果展示:

复制Sending build context to Docker daemon 3.072

kB

Step 1/10 :

ARG image

Step 2/10 : FROM $image as

stage1

---> d6e46aa2470dStep 3/10 : RUN echo "stage1 -> base from image is : $image " ---> Running in ecb7be5dd9ccstage1 -> base from image is :

### image 结果未输出

Removing intermediate container ecb7be5dd9cc

---> 04807c8d53beStep 4/10 : FROM $image as

stage11

---> d6e46aa2470dStep 5/10 : RUN echo "stage11 -> base from image is : $image " ---> Running in a90e45076345stage11 -> base from image is :

### image 结果未输出

Removing intermediate container a90e45076345

---> f2dbce837a1bStep 6/10 : FROM alpine:3.12 as

stage2

---> d6e46aa2470dStep 7/10 :

ARG image

---> Running in 5c8cec4c2f22Removing intermediate container 5

c8cec4c2f22

---> 999d9990bd91Step 8/10 : RUN echo "stage2 -> base from image is : $image " ---> Running in 4407dcb0e0bbstage2 -> base from image is : alpine:3.12

### image 结果输出

Removing intermediate container 4407

dcb0e0bb

---> e5ddd7a84f81Step 9/10 : FROM alpine:3.12 as

stage21

---> d6e46aa2470dStep 10/10 : RUN echo "stage21 -> base from image is : $image " ---> Running in 64a0a3bb090cstage21 -> base from image is :

### image 结果未输出

Removing intermediate container 64

a0a3bb090c

---> 82665f9a1037Successfully built 82665f9a10371.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.

0x03 参考文档

set-build-time-variables—build-arg

0x04 to be continue

在以后的时间, 笔者将继续讨论 ARG 在 docker buildx 多节构建时的影响和使用。

阅读剩余
THE END