docker build 不使用緩存重建鏡像


cache 機制注意事項

可以說,cache 機制很大程度上做到了鏡像的復用,降低存儲空間的同時,還大大縮短了構建時間。然而,不得不說的是,想要用好 cache 機制,那就必須了解利用 cache 機制時的一些注意事項。

1. ADD 命令與 COPY 命令:Dockerfile 沒有發生任何改變,但是命令ADD run.sh / 中 Dockerfile 當前目錄下的 run.sh 卻發生了變化,從而將直接導致鏡像層文件系統內容的更新,原則上不應該再使用 cache。那么,判斷 ADD 命令或者 COPY 命令后緊接的文件是否發生變化,則成為是否延用 cache 的重要依據。Docker 采取的策略是:獲取 Dockerfile 下內容(包括文件的部分 inode 信息),計算出一個唯一的 hash 值,若 hash 值未發生變化,則可以認為文件內容沒有發生變化,可以使用 cache 機制;反之亦然。

2. RUN 命令存在外部依賴:一旦 RUN 命令存在外部依賴,如RUN apt-get update,那么隨着時間的推移,基於同一個基礎鏡像,一年的 apt-get update 和一年后的 apt-get update, 由於軟件源軟件的更新,從而導致產生的鏡像理論上應該不同。如果繼續使用 cache 機制,將存在不滿足用戶需求的情況。Docker 一開始的設計既考慮了外部依賴的問題,用戶可以使用參數 --no-cache 確保獲取最新的外部依賴,命令為docker build --no-cache -t="my_new_image" .

3. 樹狀的鏡像關系決定了,一次新鏡像的成功構建將導致后續的 cache 機制全部失效:這一點很好理解,一旦產生一個新的鏡像,同時意味着產生一個新的鏡像 ID,而當前宿主機環境中肯定不會存在一個鏡像,此鏡像 ID 的父鏡像 ID 是新產生鏡像的ID。這也是為什么,書寫 Dockerfile 時,應該將更多靜態的安裝、配置命令盡可能地放在 Dockerfile 的較前位置。

 

 

 

使用Dockerfile構建鏡像可以利用它的緩存功能:只有在命令已更改的情況下,才會重建已構建的步驟。下面是重新構建之前涉及到的to-do app的示例:

  1. $ docker build .
  2. Sending build context to Docker daemon  2.56 kB
  3. Sending build context to Docker daemon
  4. Step 0 : FROM node
  5.   ---> 91cbcf796c2c
  6. Step 1 : MAINTAINER ian.miell@gmail.com
  7.  ---> Using cache
  8. Indicates you’re using the cache
  9. Specifies the cached image/layer ID
  10.    ---> 8f5a8a3d9240
  11. Step 2 : RUN git clone -q https://github.com/docker-in-practice/todo.git
  12.  ---> Using cache
  13.  ---> 48db97331aa2
  14. Step 3 : WORKDIR todo
  15.  ---> Using cache
  16.  ---> c5c85db751d6
  17. Step 4 : RUN npm install > /dev/null
  18.  ---> Using cache
  19.  ---> be943c45c55b
  20. Step 5 : EXPOSE 8000
  21.  ---> Using cache
  22.  ---> 805b18d28a65
  23. Step 6 : CMD npm start
  24.  ---> Using cache
  25.  ---> 19525d4ec794
  26. Successfully built 19525d4ec794

緩存非常有用並且省時間,不過有時候docker緩存的行為不都能達到你的期望。
用以上Dockerfile作為示例,假設你更改了代碼並push到Git倉庫。新代碼不會check out下來,因為git clone命令沒有更改。在Docker看來git clone的步驟一樣,所以使用了緩存。
在這種情況下,你可能不想開啟docker的緩存了。

問題

你想不用緩存重建Dockerfile。

解決方法

構建鏡像時使用–no-cache參數。

討論

為了強制docker構建鏡像時不用緩存,執行帶–no-cache參數的docker build命令。下面的示例是使用了–no-cache構建鏡像。

  1. $ docker build --no-cache .
  2. Sending build context to Docker daemon  2.56 kB
  3. Sending build context to Docker daemon
  4. Step 0 : FROM node
  5.  ---> 91cbcf796c2c
  6. Step 1 : MAINTAINER ian.miell@gmail.com
  7.  ---> Running in ca243b77f6a1
  8.  ---> 602f1294d7f1
  9. Removing intermediate container ca243b77f6a1
  10. Step 2 : RUN git clone -q https://github.com/docker-in-practice/todo.git
  11.  ---> Running in f2c0ac021247
  12.  ---> 04ee24faaf18
  13. Removing intermediate container f2c0ac021247
  14. Step 3 : WORKDIR todo
  15.  ---> Running in c2d9cd32c182
  16.  ---> 4e0029de9074
  17. Removing intermediate container c2d9cd32c182
  18. Step 4 : RUN npm install > /dev/null
  19.  ---> Running in 79122dbf9e52
  20. npm WARN package.json todomvc-swarm@0.0.1 No repository field.
  21.  ---> 9b6531f2036a
  22. Removing intermediate container 79122dbf9e52
  23. Step 5 : EXPOSE 8000
  24.  ---> Running in d1d58e1c4b15
  25.  ---> f7c1b9151108
  26. Removing intermediate container d1d58e1c4b15
  27. Step 6 : CMD npm start
  28.  ---> Running in 697713ebb185
  29.  ---> 74f9ad384859
  30. Removing intermediate container 697713ebb185
  31. Successfully built 74f9ad384859

以上的構建鏡像步驟沒有使用到緩存,每一層的鏡像ID都與之間的不同。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM