建置快取失效
建置映像檔時,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.20 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 .
建置密鑰
建置 secrets 的內容不是建置快取的一部分。變更 secret 的值不會導致快取失效。
如果您想要在變更 secret 值後強制快取失效,您可以傳遞一個具有任意值的建置引數,當您變更 secret 時也變更該引數。建置引數會導致快取失效。
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 .
Secrets 的屬性(例如 ID 和掛載路徑)會參與快取校驗和的計算,如果變更,則會導致快取失效。