output: 'standalone' khiến next build sinh ra thư mục .next/standalone chứa server.js cùng đúng những dependency thực sự được dùng (dò qua đồ thị import).
Nhờ đó image Docker không cần mang cả node_modules, giảm từ vài trăm MB xuống vài chục.
dockerfile
FROM node:22-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
CMD ["node", "server.js"]Hai dòng COPY cho static và public là bắt buộc — standalone không gộp sẵn chúng, quên là trang mất hết CSS và ảnh.
Những thứ hay hỏng khi rời nền tảng managed:
- Chạy nhiều instance. ISR cache và Data Cache mặc định ghi xuống đĩa cục bộ của từng container. Hai pod sẽ revalidate lệch nhau, người dùng thấy nội dung nhảy qua nhảy lại. Cần cấu hình cache handler dùng chung (Redis) hoặc volume chia sẻ.
revalidatePathchỉ tác động lên đúng instance nhận request, không lan sang pod khác — cùng một gốc rễ với vấn đề trên.- Biến môi trường thời điểm build.
NEXT_PUBLIC_*bị nội tuyến lúcnext build, nên phải truyền vào stage builder chứ không phải lúcdocker run. - Tối ưu ảnh. Không còn hạ tầng ảnh của nền tảng; cần
sharptrong image, hoặc trỏimages.loadersang một CDN ảnh bên ngoài. - Container tự động tắt. Nếu nền tảng dừng container khi rảnh, cache trên đĩa mất theo, request đầu sau khi khởi động lại sẽ chậm.