តិចនិកប្រើប្រាស់ Multi-stage Builds ដើម្បីកាត់បន្ថយទំហំ Docker Image សម្រាប់ Next.js App
ស្វែងយល់ពីរបៀបប្រើប្រាស់ Multi-stage Docker Builds រួមជាមួយ feature standalone របស់ Next.js ដើម្បីកាត់បន្ថយទំហំ Docker Image ពីជិត 1GB មកនៅសល់ក្រោម 100MB ជួយឱ្យការ Deploy កាន់តែលឿន និងចំណាយទំហំផ្ទុកតិច។
ពេលដែលយើងបង្កើត Docker Image សម្រាប់ Next.js App តាមបែបធម្មតា (ដោយគ្រាន់តែ copy source code ទាំងមូល និង run npm install) យើងជួបបញ្ហាមួយគឺ ទំហំ Image ធំខ្លាំង រហូតដល់ទៅជិត 1GB ឬលើសពីនេះ។ មូលហេតុគឺដោយសារវាផ្ទុកទៅដោយ DevDependencies, Caches និង Source files ដែលមិនចាំបាច់សម្រាប់ដំណើរការនៅលើ Productionbox។
នៅក្នុង field note នេះ ខ្ញុំនឹងបង្ហាញពីរបៀបប្រើប្រាស់ Multi-stage Builds រួមជាមួយ feature output: 'standalone' របស់ Next.js ដើម្បីបង្រួម Image ឱ្យមកនៅតូចបំផុត (ក្រោម 100MB)។
ជំហានទី ១៖ កំណត់ Next.js Config ឱ្យទៅជា Standalone
Next.js មាន feature មួយឈ្មោះថា standalone ដែលវាមានតួនាទីប្រមូលផ្តុំតែ files ណាដែលចាំបាច់បំផុតសម្រាប់ run application (រួមទាំង node_modules កម្រិតស្រាលដែលចាំបាច់) ដោយមិនចាំបាច់យក files ផ្សេងទៀតឡើយ។
សូមបើក next.config.js (ឬ next.config.mjs) រួចបន្ថែម output: 'standalone':
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone', // បន្ថែមបន្ទាត់នេះ
};
export default nextConfig;ជំហានទី ២៖ សរសេរ Multi-stage Dockerfile
យើងនឹងបែងចែក Dockerfile របស់យើងជា ៣ ដំណាក់កាល (Stages)៖
- Deps Stage: សម្រាប់ដំឡើង
node_modulesទាំងអស់។ - Builder Stage: សម្រាប់ build project (យក
node_modulesពី stage ទី១ មកប្រើ)។ - Runner Stage: យកតែ production artifacts ដែល build រួចពី stage ទី២ មក run (មិនយក source code ឬ devDependencies មកឡើយ)។
សូមបង្កើត file ឈ្មោះ Dockerfile នៅក្នុង root project របស់អ្នក៖
# --- Stage 1: Base & Dependencies ---
FROM node:20-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Copy package management files
COPY package.json package-lock.json* ./
RUN npm ci
# --- Stage 2: Builder ---
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# បិទការប្រមូល Telemetry របស់ Next.js កំឡុងពេល build (Optional)
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
# --- Stage 3: Runner (Production) ---
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
# បង្កើត System user ដើម្បីសុវត្ថិភាព (មិន run ក្នុងនាមជា root)
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Copy តែ files ដែលចាំបាច់ពី stage មុន
COPY --from=builder /app/public ./public
# ល្បិចសំខាន់៖ យកផលិផល standalone និង static មកប្រើ
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# Run node direct ទៅកាន់ server.js ដែលបង្កើតដោយ standalone mode
CMD ["node", "server.js"]ជំហានទី ៣៖ បង្កើត .dockerignore
ដើម្បីកុំឱ្យ Docker លួច copy របស់មិនចាំបាច់ចូលទៅក្នុង Build context មុននឹងចាប់ផ្តើម សូមបង្កើត file .dockerignore មួយ៖
.next
node_modules
build
.git
.gitignore
README.md
Dockerfile
.dockerignoreលទ្ធផល និងការសន្និដ្ឋាន
នៅពេលដែលអ្នក build Docker image នេះតាមរយៈបញ្ជា៖
docker build -t my-nextjs-app .អ្នកនឹងឃើញថាទំហំ Image ចុងក្រោយគឺស្ថិតនៅក្នុងរង្វង់ ~80MB ទៅ 120MB តែប៉ុណ្ណោះ (អាស្រ័យលើទំហំ assets ក្នុង folder public របស់អ្នក)។
ការធ្វើបែបនេះមិនត្រឹមតែជួយសន្សំសំចៃ space នៅលើ server របស់អ្នកនោះទេ ប៉ុន្តែវាថែមទាំងជួយឱ្យការធ្វើ CI/CD Pipeline និងការទាញយក Image (Docker pull) ទៅកាន់ Production server ប្រព្រឹត្តទៅបានលឿនជាងមុនដាច់តែម្តង!
