Dockerfile 中 ARG 的使用與其做用域(scope)探究

使用 ARG 能夠有效的複用 Dockerfile。每次鏡像更新,只須要動態的在 build 命令中傳入新的參數值便可。docker

0x01 結論


  1. 在第一個 FROM 以前的全部 ARG , 在全部 FROM 中生效, 僅在 FROM 中生效
  2. 在 FROM 後的 ARG, 僅在當前 FROM 做用域生效。即盡在當前 階段 (stage) 生效

對照組解析

在隨後的 Dockerfile 中, 只定義了一個變量 image , 並在 FROM 和 stage 中重複使用ide

  1. 對照組1: stage1 和 stage11 均在 FROM 中使用了變量 $image: 做用域在全部 FROM 中
  • 成功拉取 FROM $image 並完成 layer 構建
  • 可是在 RUN 中沒法正確輸出結果,即 image 的值 alpine:3.12
    2 . 對照組2: stage1 vs stage2: 做用域在 FROM stage 內部
  • 在 stage2 的做用域中聲明瞭 ARG image,且能正確輸出結果。
    3 . 對照組3: stage2 vs stage21: 做用域僅在當前 FROM stage 內部
  • 雖然 stage2 在 stage21 上方且聲明瞭 ARG image, 但 stage21 仍然不能不能正確輸出結果。

0x02 實驗過程


  1. 建立 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 :
  1. 執行 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 多節構建時的影響和使用。ui

相關文章
相關標籤/搜索