使用 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.12

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