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
docker build --no-cache -t="my_new_image" .
3. 樹狀的映象關係決定了,一次新映象的成功構建將導致後續的 cache 機制全部失效:這一點很好理解,一旦產生一個新的映象,同時意味著產生一個新的映象 ID,而當前宿主機環境中肯定不會存在一個映象,此映象 ID 的父映象 ID 是新產生映象的ID。這也是為什麼,書寫 Dockerfile 時,應該將更多靜態的安裝、配置命令儘可能地放在 Dockerfile 的較前位置。
使用Dockerfile構建映象可以利用它的快取功能:只有在命令已更改的情況下,才會重建已構建的步驟。下面是重新構建之前涉及到的to-do app的示例:
$ docker build . Sending build context to Docker daemon 2.56 kB Sending build context to Docker daemon Step 0 : FROM node ---> 91cbcf796c2c Step 1 : MAINTAINER [email protected] ---> Using cache Indicates you’re using the cache Specifies the cached image/layer ID ---> 8f5a8a3d9240 Step 2 : RUN git clone -q https://github.com/docker-in-practice/todo.git ---> Using cache ---> 48db97331aa2 Step 3 : WORKDIR todo ---> Using cache ---> c5c85db751d6 Step 4 : RUN npm install > /dev/null ---> Using cache ---> be943c45c55b Step 5 : EXPOSE 8000 ---> Using cache ---> 805b18d28a65 Step 6 : CMD npm start ---> Using cache ---> 19525d4ec794 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構建映象。
$ docker build --no-cache . Sending build context to Docker daemon 2.56 kB Sending build context to Docker daemon Step 0 : FROM node ---> 91cbcf796c2c Step 1 : MAINTAINER [email protected] ---> Running in ca243b77f6a1 ---> 602f1294d7f1 Removing intermediate container ca243b77f6a1 Step 2 : RUN git clone -q https://github.com/docker-in-practice/todo.git ---> Running in f2c0ac021247 ---> 04ee24faaf18 Removing intermediate container f2c0ac021247 Step 3 : WORKDIR todo ---> Running in c2d9cd32c182 ---> 4e0029de9074 Removing intermediate container c2d9cd32c182 Step 4 : RUN npm install > /dev/null ---> Running in 79122dbf9e52 npm WARN package.json [email protected] No repository field. ---> 9b6531f2036a Removing intermediate container 79122dbf9e52 Step 5 : EXPOSE 8000 ---> Running in d1d58e1c4b15 ---> f7c1b9151108 Removing intermediate container d1d58e1c4b15 Step 6 : CMD npm start ---> Running in 697713ebb185 ---> 74f9ad384859 Removing intermediate container 697713ebb185 Successfully built 74f9ad384859
以上的構建映象步驟沒有使用到快取,每一層的映象ID都與之間的不同。
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的示例:
$ docker build . Sending build context to Docker daemon 2.56 kB Sending build context to Docker daemon Step 0 : FROM node ---> 91cbcf796c2c Step 1 : MAINTAINER [email protected] ---> Using cache Indicates you’re using the cache Specifies the cached image/layer ID ---> 8f5a8a3d9240 Step 2 : RUN git clone -q https://github.com/docker-in-practice/todo.git ---> Using cache ---> 48db97331aa2 Step 3 : WORKDIR todo ---> Using cache ---> c5c85db751d6 Step 4 : RUN npm install > /dev/null ---> Using cache ---> be943c45c55b Step 5 : EXPOSE 8000 ---> Using cache ---> 805b18d28a65 Step 6 : CMD npm start ---> Using cache ---> 19525d4ec794 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構建映象。
$ docker build --no-cache . Sending build context to Docker daemon 2.56 kB Sending build context to Docker daemon Step 0 : FROM node ---> 91cbcf796c2c Step 1 : MAINTAINER [email protected] ---> Running in ca243b77f6a1 ---> 602f1294d7f1 Removing intermediate container ca243b77f6a1 Step 2 : RUN git clone -q https://github.com/docker-in-practice/todo.git ---> Running in f2c0ac021247 ---> 04ee24faaf18 Removing intermediate container f2c0ac021247 Step 3 : WORKDIR todo ---> Running in c2d9cd32c182 ---> 4e0029de9074 Removing intermediate container c2d9cd32c182 Step 4 : RUN npm install > /dev/null ---> Running in 79122dbf9e52 npm WARN package.json [email protected] No repository field. ---> 9b6531f2036a Removing intermediate container 79122dbf9e52 Step 5 : EXPOSE 8000 ---> Running in d1d58e1c4b15 ---> f7c1b9151108 Removing intermediate container d1d58e1c4b15 Step 6 : CMD npm start ---> Running in 697713ebb185 ---> 74f9ad384859 Removing intermediate container 697713ebb185 Successfully built 74f9ad384859
以上的構建映象步驟沒有使用到快取,每一層的映象ID都與之間的不同。