PlusMagi's Blog By Pitt Phunsanit Backend,Cloud Computing Docker: Single-stage Build และ Multi-stage Build

Docker: Single-stage Build และ Multi-stage Build

การเปรียบเทียบระหว่าง Single-stage Build และ Multi-stage Build (โดยทั่วไปจะหมายถึงการสร้าง Container Image ด้วย Docker)




ทำความเข้าใจภาพรวม

  • Single-stage Build (แบบดั้งเดิม / ขั้นตอนเดียว)
    • ใช้ Dockerfile ที่มีคำสั่ง FROM เพียงบรรทัดเดียว
    • ขั้นตอนการติดตั้ง Tool สำหรับคอมไพล์ (Build tools, SDK, Dependencies) และขั้นตอนการรันโปรแกรม (Runtime) อยู่ใน Image เดียวกันทั้งหมด
  • Multi-stage Build (แบบหลายขั้นตอน)
    • มีคำสั่ง FROM หลายตัวใน Dockerfile เดียวกัน
    • แบ่งกระบวนการออกเป็นหลาย Stage (เช่น Stage ที่ 1 สำหรับ Build/Compile และ Stage ที่ 2 สำหรับ Runtime)
    • สามารถคัดลอก (Copy) เฉพาะ Artifacts หรือไฟล์ที่จำเป็นจาก Stage ก่อนหน้าเข้ามายัง Stage สุดท้ายได้



ตารางเปรียบเทียบประเด็นสำคัญ

หัวข้อSingle-stage BuildMulti-stage Build
ขนาดของ Image (Image Size)ใหญ่มาก เพราะรวมทั้ง Source code, SDK, Build tools, Dev dependencies และ Cache เอาไว้เล็กและกะทัดรัด เพราะมีเฉพาะ Binary/ไฟล์ที่ Build เสร็จแล้ว และ Runtime environment
ความปลอดภัย (Security)ต่ำกว่า เนื่องจากมีเครื่องมือที่ไม่จำเป็น (เช่น gcc, npm, git) และ Source code หลงเหลืออยู่ใน Image ซึ่งเพิ่ม Attack Surfaceสูงกว่า มีเฉพาะสิ่งที่จำเป็นต่อการรันโปรแกรม ลดช่องโหว่และลดความเสี่ยงจากเครื่องมือตกค้าง
ความซับซ้อนของ Dockerfileเรียบง่าย เขียนตรงไปตรงมา เข้าใจง่าย เหมาะกับการทดลองเบื้องต้นซับซ้อนกว่าเล็กน้อย ต้องออกแบบและจัดการการส่งต่อไฟล์ข้าม Stage
การจัดการ Build Script / CI/CDหากต้องการ Image ขนาดเล็ก มักต้องเขียน Bash script แยก หรือสร้าง Dockerfile 2 ไฟล์ (Builder + Runtime)จบในไฟล์เดียว ไม่ต้องพึ่งพา Script ซับซ้อนใน Pipeline CI/CD
Caching และความเร็วในการ Buildหาก Dependency เปลี่ยน อาจต้องดาวน์โหลดและ Build ใหม่ทั้งหมดLayer Caching แยกตาม Stage ได้ชัดเจน ทำให้ Build ซ้ำได้เร็วกว่า



ตัวอย่างการเปรียบเทียบด้วยโค้ด (เช่น แอปพลิเคชัน Node.js/Go)




ตัวอย่าง: Single-stage Build

Dockerfile

YAML

YAML

# ใช้ Node.js ตัวเต็ม
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# สิ่งที่ติดไปด้วย: node_modules ขนาดใหญ่, TypeScript compiler, Source code ทั้งหมด
EXPOSE 3000
CMD ["node", "dist/main.js"]

ผลลัพธ์: Image อาจมีขนาด 500MB – 1GB+




ตัวอย่าง: Multi-stage Build

Dockerfile

YAML

YAML

# Stage 1: Build Stage (ใช้ image ที่มีเครื่องมือครบ)
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Stage 2: Production Stage (ใช้ image เล็กที่สุด เฉพาะสำหรับรัน)
FROM node:18-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm install --only=production
# ก๊อปปี้เฉพาะไฟล์ที่ build เสร็จแล้วจาก Stage 1
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/main.js"]

ผลลัพธ์: Image เหลือขนาดเพียง 100MB – 150MB




สรุปคำแนะนำในการเลือกใช้

  • ใช้ Single-stage Build เมื่อ:
    • ทำโปรเจกต์ทดลอง (POC), พัฒนาในเครื่อง (Local Dev) ที่ต้องการความง่าย
    • ภาษาที่ไม่จำเป็นต้องคอมไพล์และไม่มี Dependency ฝั่ง Build (เช่น สคริปต์ Python สั้นๆ)
  • ใช้ Multi-stage Build เมื่อ:
    • เตรียม Deploy ขึ้น Production
    • ภาษาที่ต้องคอมไพล์เป็น Binary เช่น Go, Rust, C++, Java/Kotlin
    • เว็บแอปพลิเคชันยุคใหม่ (React, Vue, Angular, Next.js) ที่ต้องการให้เหลือเฉพาะไฟล์ Static / Production bundle

Exit mobile version