#Backend & Microservices#DevOps & Cloud
Docker Multi-stage Build cho Node.js và Go: Giảm image size từ 1.4GB xuống còn 65MB
📖 2 phút đọc 💬 1 phản hồi
⚡ Tóm tắt 30 giây bởi TopDev AI
AI Overview Vì sao Docker Image quá nặng là một thảm họa? Một Docker image nặng hơn 1GB mang lại hàng loạt rắc rối: - Tốn nhiều thời gian pull/push qua mạng trong quá trình CI/CD deploy. - Tốn dung lượng lưu trữ…
☰ Mục lục bài viết (5 phần) Mở / Đóng mục lục
Vì sao Docker Image quá nặng là một thảm họa?#
Một Docker image nặng hơn 1GB mang lại hàng loạt rắc rối:
- Tốn nhiều thời gian pull/push qua mạng trong quá trình CI/CD deploy.
- Tốn dung lượng lưu trữ trên Container Registry (tốn tiền lưu trữ hàng tháng).
- Chứa toàn bộ compiler, source code, devDependencies rác, tạo nên bề mặt tấn công bảo mật (Attack Surface) rộng lớn.
Nhờ kỹ thuật Multi-stage Build, chúng ta có thể tách biệt hoàn toàn môi trường Build (nặng) và môi trường Chạy Production (siêu nhẹ).
Dockerfile chuẩn cho Node.js + TypeScript#
DOCKERFILE
# Stage 1: Build source code
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Loại bỏ devDependencies để chỉ giữ lại runtime packages
RUN npm prune --production
# Stage 2: Production Runtime siêu nhẹ
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
# Chạy dưới tài khoản bảo mật non-root
USER node
COPY --from=builder --chown=node:node /app/package*.json ./
COPY --from=builder --chown=node:node /app/node_modules ./node_modules
COPY --from=builder --chown=node:node /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/main.js"]
Dockerfile cho Golang: Xuống còn 15MB với Distroless#
Với các ứng dụng viết bằng Go, chúng ta thậm chí có thể biên dịch tĩnh (static binary) và chạy trên image distroless không có cả shell bash:
DOCKERFILE
FROM golang:1.24-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o server .
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]
Kết quả so sánh dung lượng#
| Ngôn ngữ | Image Single-stage cũ | Image Multi-stage mới | Mức độ giảm |
|---|---|---|---|
| Node.js (NestJS) | 1.35 GB | 145 MB | Giảm gần 90% |
| Golang API | 820 MB | 18 MB | Giảm 97% |
Góc thảo luận#
Image Docker của dịch vụ chính bên bạn hiện nặng bao nhiêu MB? Bạn có đang chạy container bằng quyền root không?
Xem thêm nội dung liên quan:
Tác giả bài viết
Đức Huy (DevOps Specialist)
Tham gia từ thg 6 2026 · 15 bài viết · 25 phản hồi
Thảo luận
1 phản hồi
💬
Tham gia thảo luận
Cộng đồng mở · Đăng nhập 1-chạm qua Google
Bài liên quan trong #Backend & Microservices
-
Áp dụng Model Context Protocol (MCP) của Anthropic để kết nối AI với Postgres và Docker
Hoàng Nam (Tech Lead) · 💬 1 -
So sánh mô hình Embedding đa ngữ: OpenAI text-embedding-3 vs BGE-M3 vs Cohere
Minh Trí (AI Engineer) · 💬 1 -
Xây dựng Voice AI Agent thời gian thực với WebRTC và Whisper Live: Độ trễ dưới 500ms
Lan Anh (Senior Frontend) · 💬 1 -
Cấu hình Rate Limiting ở tầng Nginx và API Gateway: Chống DDOS Layer 7 hiệu quả
Đức Huy (DevOps Specialist) · 💬 1 -
Tokenization tiếng Việt của các LLM: Tại sao chi phí tiếng Việt đắt gấp 3 lần tiếng Anh?
Minh Trí (AI Engineer) · 💬 1