構建快取失效
在構建映象時,Docker 會逐步執行 Dockerfile 中的指令,並按照指定順序執行每個指令。對於每個指令,構建器會檢查是否可以從構建快取中重用該指令。
通用規則
構建快取失效的基本規則如下:
構建器首先檢查基礎映象是否已快取。然後,每個後續指令都與快取層進行比較。如果沒有快取層與該指令完全匹配,則快取失效。
在大多數情況下,將 Dockerfile 指令與相應的快取層進行比較就足夠了。但是,有些指令需要額外的檢查和說明。
對於
ADD
和COPY
指令,以及帶有繫結掛載的RUN
指令(RUN --mount=type=bind
),構建器會根據檔案元資料計算快取校驗和,以確定快取是否有效。在快取查詢期間,如果涉及的任何檔案的檔案元資料已更改,則快取會失效。在計算快取校驗和時,不考慮檔案的修改時間(
mtime
)。如果僅複製檔案的mtime
發生變化,則快取不會失效。除了
ADD
和COPY
命令外,快取檢查不檢視容器中的檔案來確定快取匹配。例如,在處理RUN apt-get -y update
命令時,不會檢查容器中更新的檔案來確定是否存在快取命中。在這種情況下,僅使用命令字串本身來查詢匹配項。
一旦快取失效,所有後續的 Dockerfile 命令都將生成新的映象,並且不再使用快取。
如果您的構建包含多個層,並且您希望確保構建快取可重用,請儘可能將指令從不經常更改的順序排列到更經常更改的順序。
RUN 指令
RUN
指令的快取不會在構建之間自動失效。假設您的 Dockerfile 中有一個安裝 curl
的步驟:
FROM alpine:3.21 AS install
RUN apk add curl
這並不意味著您的映象中的 curl
版本始終是最新的。一週後重新構建映象仍將獲得與以前相同的軟體包。要強制重新執行 RUN
指令,您可以:
- 確保它之前的一個層已更改
- 在構建之前使用
docker builder prune
清除構建快取 - 使用
--no-cache
或--no-cache-filter
選項
--no-cache-filter
選項允許您指定要使其快取失效的特定構建階段。
$ docker build --no-cache-filter install .
構建機密
構建秘密的內容不屬於構建快取。更改秘密的值不會導致快取失效。
如果您想在更改秘密值後強制快取失效,您可以傳遞一個帶有任意值的構建引數,當更改秘密時,您也更改該引數。構建引數確實會導致快取失效。
FROM alpine
ARG CACHEBUST
RUN --mount=type=secret,id=TOKEN,env=TOKEN \
some-command ...
$ TOKEN="tkn_pat123456" docker build --secret id=TOKEN --build-arg CACHEBUST=1 .
秘密的屬性(例如 ID 和掛載路徑)確實參與快取校驗和,如果更改,將導致快取失效。