Dockerfile layer cache
理解 layer cache 才知道為什麼 Dockerfile 的指令順序會影響 build 速度。
核心原則
- 每條指令是一層,是 cache 的基本單位。Docker 比對指令字串與相關檔案的 checksum,完全相同才命中快取。
- 失效會串聯:某一層 cache 失效,後面所有層一律重建,不管它們本身有沒有變。
| 指令 | 觸發失效 |
|---|---|
FROM | base image digest 改變 |
RUN | 指令字串改變(不看實際輸出,apt-get update 抓到新版本不會讓 cache 失效) |
COPY / ADD | 來源檔案的 checksum 改變(mtime 不計) |
ENV / ARG / WORKDIR 等 | 指令字串改變 |
指令排序最佳化
原則:變動頻率低的指令放前面,高的放後面。RUN apt-get update 的雷:update 與 install 要寫在同一條 RUN,否則 update 那層被快取後,install 可能裝到舊版本:
強制跳過與清理
Cache mount(跨 build 持久化套件快取)
讓套件下載快取跨 build 持久化(不進映像層):--mount=type=cache 的快取不進 image layer,只在 builder 端持久化,比傳統做法省 build 時間。
最佳實踐範本
把原則收成一份可直接抄的範本:RUN 並清 apt 快取(rm -rf /var/lib/apt/lists/*)、pip install --no-cache-dir 不把 pip 快取留進映像、固定基底 tag、切非 root USER、用 .dockerignore 縮小 context、WORKDIR 用絕對路徑取代 RUN cd。
注意事項與安全
- 別用
latest:基底固定major.minor(或更嚴格用 digest@sha256:...),避免基底悄悄換版本。 - 切非 root
USER:預設 root 跑容器風險高,建專用使用者再切過去。 - 機密別進 Dockerfile:
ARG/ENV會留在docker history,密碼金鑰用執行期注入(docker run --env/ Composeenv_file/ secrets),不要寫死在 Dockerfile。 ADD下載 URL 要當心:快取與認證行為複雜,需要下載多用RUN curl並驗 checksum;一般複製優先COPY。
接下來
- Dockerfile 指令逐一:USER、HEALTHCHECK 等指令細節。
- 配合 Python 程式:multi-stage 進一步縮小映像。