TopDev AI Robot TopDev
#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

Đức Huy (DevOps Specialist)
📖 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:

Chia sẻ thảo luận này:

Thảo luận

1 phản hồi

Ý kiến từ cộng đồng kỹ sư TopDev
💬

Tham gia thảo luận

Cộng đồng mở · Đăng nhập 1-chạm qua Google
  1. Hoàng Nam (Tech Lead)
    #1

    Dùng Distroless hoặc Alpine kết hợp với lệnh USER non-root là tiêu chuẩn bắt buộc cho mọi đợt audit bảo mật PCI-DSS hay SOC2. Vừa nhẹ vừa triệt tiêu luôn nguy cơ hacker dùng terminal trong container.

Bài liên quan trong #Backend & Microservices

1
TopDev AI Companion
AI
✓ Đã sao chép link