Docker Build 快取失效指南:哪些 Dockerfile 指令會導致 Cache Miss

5 分鐘閱讀

小技巧:

我習慣在 CI 上將每次執行時的流水號以 RELEASE build-arg 傳入,並且在 不希望使用到 cache 的步驟前面插入這個 ARG。

請查看這個範本: CI, Containerfile

琳 avatar

docker build 中 哪些 dockerfile 指令會導致不 cache

Felo Search avatar
Felo Search

在使用 docker build 建立映像檔時,Docker 會根據 Dockerfile 中的指令建立快取層,以加快後續的建置速度。然而,某些指令的使用方式會導致快取失效,迫使 Docker 重新執行相關步驟。以下是幾種常見會導致快取失效的 Dockerfile 指令:

1. 使用 RUN 指令搭配動態內容

RUN 指令中包含動態生成的內容,如時間戳或隨機數,會導致每次建置時該指令的快取層無法重用。例如:

RUN echo $(date) > build_date.txt

每次建置時,$(date) 的結果都不同,導致該步驟的快取失效12

2. 修改 ENVARG 變數

ENVARG 指令用於設置環境變數和建置參數。如果這些變數的值在不同的建置中發生變化,會導致後續指令的快取失效。例如:

ARG CACHE_DATE=not_a_date
ENV BUILD_DATE=$CACHE_DATE

改變 CACHE_DATE 的值會使 ENV 指令無法使用快取13

3. 更改 COPYADD 指令的來源內容

COPYADD 指令會將主機上的檔案或目錄複製到映像檔中。如果來源檔案發生變化,Docker 將無法使用快取,需重新執行這些指令。例如:

COPY . /app

每當專案中的檔案有變動,COPY 指令的快取將失效,導致整個步驟重新執行24

4. 引用未固定的基礎映像版本

在 Dockerfile 中使用未固定版本的基礎映像(如 ubuntu:latest)會導致每次建置時基礎映像可能更新,從而使快取失效。建議使用具體的版本標籤,例如 ubuntu:20.04,以確保一致性和快取的有效性52

5. 使用 --no-cache 標誌

在建置映像時,使用 --no-cache 標誌會強制 Docker 忽略所有快取層,從頭開始執行所有指令。這對於確保每次建置都是全新的,但會增加建置時間467

docker build --no-cache -t my-image:my-tag .

6. 引入不穩定的依賴或外部資源

如果 Dockerfile 中的指令依賴於外部資源(如從網路下載檔案),而這些資源經常變動,會導致快取失效。例如:

RUN wget https://example.com/file.tar.gz

每次建置時,如果 file.tar.gz 有更新,該指令的快取將無法使用23

如何有效管理 Docker 快取

為了最大化利用 Docker 的快取機制,建議遵循以下最佳實踐:

透過這些策略,可以有效減少不必要的建置時間,提升開發效率83

  1. How can I prevent a Dockerfile instruction from being cached? - Stack Overflow ↩2

  2. Build cache invalidation | Docker Docs ↩2 ↩3 ↩4

  3. Docker Cache - How to Do a Clean Image Rebuild and Clear Docker's Cache ↩2 ↩3

  4. Building Dockerfile Without Cache | by Nikhil YN | Medium ↩2

  5. Best practices | Docker Docs

  6. How to build an image without the Docker cache | LinkedIn

  7. How to build an image without the Docker cache

  8. Using the build cache | Docker Docs