Dockerfile 分層快取由上往下連鎖失效
Dockerfile 每一行指令產生一個 layer。Docker build 時檢查這層的指令與輸入檔案有沒有變,沒變就直接用快取——但一旦某層失效,它後面的所有層都會跟著失效重跑。
差 36 倍的兩種寫法
# ❌ 改一個字就重裝所有套件(約 180 秒)
COPY . .
RUN npm ci
# ✅ 依賴清單沒變就沿用快取(約 5 秒)
COPY package*.json ./
RUN npm ci
COPY . .黃金原則:越少改動的放越上面
FROM、系統套件安裝(幾乎不變)- 複製依賴清單(
package.json/requirements.txt/go.mod) - 安裝依賴(只有依賴變了才重跑)
- 複製原始碼(天天在改)
CMD/ENTRYPOINT
其他語言同理:Python 先 COPY requirements.txt 再 pip install;Go 先 COPY go.mod go.sum 再 go mod download。
查哪一層在肥
docker history my-app:1.0 # 逐層看大小與產生它的指令⚠️ 在後面的層 rm 掉檔案不會讓 image 變小——前一層還留著那些資料。必須在同一個 RUN 裡面裝完就刪(例如 apt-get install ... && rm -rf /var/lib/apt/lists/*)。同理 apt-get update 要跟 install 寫在同一個 RUN,分開寫會因為快取拿到過期的套件索引。
搭配 多階段建置把建置工具擋在最終 image 之外 一起用。