DockerTẬP 007⏱️ Đọc ~2 phút

Tối Ưu Dockerfile Layer Caching Giảm 80% Thời Gian Build

Trong các hệ thống CI/CD hiện đại, thời gian build Docker image chiếm phần lớn thời gian chạy của toàn bộ pipeline. Nếu mỗi lần sửa một dòng code nhỏ mà pipeline phải tải lại hàng...

Tối Ưu Dockerfile Layer Caching Giảm 80% Thời Gian Build

Trong các hệ thống CI/CD hiện đại, thời gian build Docker image chiếm phần lớn thời gian chạy của toàn bộ pipeline. Nếu mỗi lần sửa một dòng code nhỏ mà pipeline phải tải lại hàng trăm MB thư viện, năng suất làm việc của cả team sẽ bị kéo tụt thảm hại.

Bí quyết nằm ở việc hiểu rõ cơ chế Layer Caching của Docker.


1. Nguyên lý bất biến: Top-to-Bottom Cache Invalidation

Mỗi lệnh trong Dockerfile (FROM, RUN, COPY, ADD) tạo ra một Layer chỉ đọc (Read-only Layer).
- Docker lưu cache cho từng layer dựa trên câu lệnh và checksum của các file được copy vào.
- Quy tắc hiệu ứng domino: Nếu một layer bị thay đổi (Cache Miss), toàn bộ các layer phía sau nó đều bị vô hiệu hoá cache và bắt buộc phải chạy lại từ đầu!


2. Sai lầm kinh điển: Copy toàn bộ code trước khi cài thư viện

Cách viết SAI (Mỗi lần đổi 1 dòng code là phải npm install lại từ đầu):

FROM node:20-alpine
WORKDIR /app

# SAI LẦM: Copy toàn bộ source code vào trước
COPY . .

# Mỗi lần sửa file code nhỏ, dòng này lại chạy lại mất 3-5 phút!
RUN npm install

CMD ["node", "server.js"]

Cách viết ĐÚNG (Tách file định nghĩa phụ thuộc ra trước):

FROM node:20-alpine
WORKDIR /app

# BƯỚC 1: Chỉ copy file manifest mô tả thư viện
COPY package*.json ./

# BƯỚC 2: Cài thư viện (Layer này được cache, không bao giờ chạy lại trừ khi thêm package mới)
RUN npm ci --only=production

# BƯỚC 3: Mới copy toàn bộ source code ứng dụng vào
COPY . .

CMD ["node", "server.js"]

3. Chiến thuật đỉnh cao: Multi-Stage Build

Multi-stage build cho phép bạn dùng một môi trường đầy đủ công cụ (SDK, Compiler) để biên dịch code, nhưng chỉ copy sản phẩm cuối cùng (binary/dist) sang một base image siêu nhẹ để chạy trên production.

Ví dụ ứng dụng Golang:

# STAGE 1: Build stage (Chứa compiler Go nặng ~800MB)
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o server .

# STAGE 2: Production stage (Dùng distroless hoặc scratch siêu sạch)
FROM gcr.io/distroless/static-debian12
WORKDIR /
COPY --from=builder /app/server /server
USER nonroot:nonroot
ENTRYPOINT ["/server"]

Kết quả: Dung lượng image giảm từ 850MB xuống chỉ còn 12MB! Giảm thiểu 99% bề mặt tấn công bảo mật và đẩy thời gian kéo image trên K8s xuống dưới 2 giây.

🎬 VIDEO REEL THỰC CHIẾN (TÓM TẮT 60 GIÂY)

Bóc Tách Trực Quan: Tối Ưu Dockerfile Layer Caching Giảm 80% Thời Gian Build

Xem video mô phỏng động trực quan nguyên lý hoạt động và thao tác lệnh thực tế để nắm trọn vẹn kiến thức chỉ trong 60 giây.