使用 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 :
執行docker build 命令:
# docker build --build-arg image=alpine:3.12 --no-cache .
build 結果展示:
Sending build context to Docker daemon 3.072kB
Step 1/10 : ARG image
Step 2/10 : FROM $image as stage1
---> d6e46aa2470d
Step 3/10 : RUN echo "stage1 -> base from image is : $image "
---> Running in ecb7be5dd9cc
stage1 -> base from image is : ### image 結果未輸出
Removing intermediate container ecb7be5dd9cc
---> 04807c8d53be
Step 4/10 : FROM $image as stage11
---> d6e46aa2470d
Step 5/10 : RUN echo "stage11 -> base from image is : $image "
---> Running in a90e45076345
stage11 -> base from image is : ### image 結果未輸出
Removing intermediate container a90e45076345
---> f2dbce837a1b
Step 6/10 : FROM alpine:3.12 as stage2
---> d6e46aa2470d
Step 7/10 : ARG image
---> Running in 5c8cec4c2f22
Removing intermediate container 5c8cec4c2f22
---> 999d9990bd91
Step 8/10 : RUN echo "stage2 -> base from image is : $image "
---> Running in 4407dcb0e0bb
stage2 -> base from image is : alpine:3.12 ### image 結果輸出
Removing intermediate container 4407dcb0e0bb
---> e5ddd7a84f81
Step 9/10 : FROM alpine:3.12 as stage21
---> d6e46aa2470d
Step 10/10 : RUN echo "stage21 -> base from image is : $image "
---> Running in 64a0a3bb090c
stage21 -> base from image is : ### image 結果未輸出
Removing intermediate container 64a0a3bb090c
---> 82665f9a1037
Successfully built 82665f9a1037
0x03 參考文檔
- set-build-time-variables—build-arg
0x04 to be continue
在以后的時間, 筆者將繼續討論 ARG 在 docker buildx 多節構建時的影響和使用。