Multi-stage build dùng nhiều FROM để tách môi trường build khỏi image runtime — image production không còn build tool, source code hay dev dependency.
dockerfile
# Stage 1 — build: compile TypeScript, bundle asset
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2 — runtime: chỉ lấy artifact cần thiết
FROM node:20-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/server.js"]- Dung lượng: từ ~1GB (
node:20kèm dev deps + source + build tool) xuống ~150MB (node:20-alpinechỉ còn prod deps + artifact đã build). Riêng base image alpine đã là ~5MB so với ~900MB của node đầy đủ. - Bảo mật: không còn TypeScript compiler, webpack và đồng bọn trong image production nên bề mặt tấn công nhỏ hẳn.
- Build argument:
ARG NODE_ENV=productioncho phép đổi hành vi theo từng stage, truyền vào bằngdocker build --build-arg. - Named stage: đặt tên bằng
ASrồiCOPY --from=builder; vàdocker build --target buildercho phép build tới đúng stage đó để soi lỗi build.