Docker Multi-Stage Build
Multi-stage build giúp mình tạo image Docker nhỏ gọn, an toàn hơn bằng cách tách riêng môi trường build với môi trường chạy thật (runtime).
Vấn đề
Dockerfile kiểu truyền thống nhét luôn build tool vào image cuối cùng:
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]
Kết quả: image ~1GB, cõng theo cả đống dependency build không cần thiết!
Cách giải quyết: Multi-Stage Build
# Stage build
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage production
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]
Kết quả: image chỉ còn ~200MB, gọn lỏn với đúng dependency cần chạy!
Được cái gì
- Image nhỏ hơn: giảm 5-10 lần dung lượng
- Deploy nhanh hơn: ít data phải truyền
- Bảo mật tốt hơn: ít bề mặt tấn công
- Production sạch sẽ: không cõng build tool theo
Áp dụng cho app Laravel
# Composer dependencies
FROM composer:2 AS composer
WORKDIR /app
COPY composer.* ./
RUN composer install --no-dev --optimize-autoloader
# Node assets
FROM node:18 AS node
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production
FROM php:8.3-fpm-alpine
WORKDIR /var/www
COPY --from=composer /app/vendor ./vendor
COPY --from=node /app/public/build ./public/build
COPY . .
Sơ đồ luồng
Multi-stage build là best practice của Docker mà dev nào cũng nên xài!
Thử thách
Luyện tập ngay điều vừa học. Viết lời giải, mở gợi ý nếu bí.
Code khởi tạo
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD ["node", "dist/server.js"]
Lời giải của bạn
# --- build stage ---
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# --- runtime stage (slim) ---
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/server.js"]

