an.id.vnv2.0
Back to blog list

Tối ưu hóa Docker Image với Multi-stage Builds

Cách viết Dockerfile thông minh để giảm dung lượng file ảnh (image size) từ hàng GB xuống chỉ còn vài MB.

July 14, 2026
dockerdevopscontainersci-cd

Tối ưu hóa Docker Image với Multi-stage Builds

Khi triển khai ứng dụng lên production thông qua Kubernetes hoặc Docker Compose, dung lượng của Docker Image đóng vai trò rất quan trọng đối với tốc độ khởi tạo dịch vụ và bảo mật hệ thống.

Một Docker image chứa quá nhiều file rác và công cụ phát triển không cần thiết sẽ làm tăng nguy cơ bị tấn công bề mặt (attack surface). Multi-stage builds là vũ khí mạnh mẽ nhất giúp giải quyết bài toán này.


1. Vấn đề của Dockerfile truyền thống

Hãy xem xét một Dockerfile Node.js thông thường:

FROM node:22
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "run", "start"]

Image sinh ra từ file này có thể nặng tới 1.2 GB vì nó chứa toàn bộ mã nguồn TypeScript, các devDependencies nặng nề và nhân Node.js đầy đủ.


2. Giải pháp: Multi-stage Builds

Chúng ta chia quy trình build thành 2 giai đoạn: Giai đoạn xây dựng (Builder) và Giai đoạn vận hành (Runner). Giai đoạn 2 chỉ copy các file đã build hoàn chỉnh và loại bỏ mọi file phát triển dư thừa.

# Stage 1: Build ứng dụng
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Chạy ứng dụng thực tế
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist

EXPOSE 3000
CMD ["node", "dist/main.js"]

3. Kết quả đạt được

Nhờ bọc bằng nhân Alpine Linux gọn nhẹ (node:22-alpine) và loại bỏ hoàn toàn devDependencies cùng mã nguồn TypeScript gốc, dung lượng Docker Image đã giảm từ 1.2 GB xuống còn dưới 150 MB! Tốc độ pull và deployment trên cụm K3s của bạn sẽ cải thiện rõ rệt.