Nattrio
Posted on May 29, 2023
สวัสดีชาว Gopher ทุกท่าน ในปัจจุบันการใช้ Container สำหรับพัฒนาแอปอย่าง Docker เป็นที่นิยมอย่างมาก เนื่องจากช่วยในการจัดการ environment และ library ให้เหมือนกันได้ไม่ว่าจะอยู่ที่ไหนก็ตาม
อย่างไรก็ดี ปัญหาการ "บวม" (Docker image bloating) หรือก็คือ image มีขนาดใหญ่เกินความจำเป็นนั้น สามารถเกิดขึ้นได้ถ้าไม่จัดการให้ดี ทางออกอื่นๆ ที่ช่วยได้ เช่น
- ใช้
dockerignore
เพื่อไม่ให้เพิ่มไฟล์ที่ไม่ต้องการ - เลือกใช้ distroless/minimal base image เพื่อลดขนาดให้ได้มากที่สุด
ต้องเข้าใจว่าส่วนที่ใช้ทำในตอน build แอปพลิเคชันนั้น พอเสร็จแล้วมักจะไม่ถูกนำมาใช้ต่อตอนที่แอปกำลังรัน ถ้าเรานำทั้งหมดมาใช้ก็จะทำให้บวมได้ ในบทความนี้จะนำเสนออีกวิธีที่จะแยกส่วนที่เป็น build tool ออก ให้เหลือเฉพาะส่วนที่จำเป็นต่อการรันแอปนั่นเอง เรียกว่า Multi-stage builds
Docker : Multi-Stage Builds
Multi-stage builds จะช่วยลดขนาดของ container ให้เล็กลงได้ ด้วยการแตกขั้นตอนออกเป็นหลายๆ stage ย่อย แต่ละ stage จะส่งผลลัพธ์ต่อไปยัง stage ถัดไป
Demo
เราสามารถใช้แอปนี้ GitHub เป็นตัวอย่างเบื้องต้นในทดสอบ
ในการเปรียบเทียบเพื่อให้เห็นภาพชัด จะทดสอบการ build ทั้งสองรูปแบบ
- ใช้ Dockerfile ในการ build แบบปกติ
FROM golang:1.18-alpine
WORKDIR /crud
COPY . .
RUN go mod download
EXPOSE 2565
RUN go build -o /test main.go
CMD [ "/test" ]
- ใช้ Dockerfile ในการทำ Multi-Stage build ซึ่งจะแบ่งเป็น 2 environment ที่แตกต่างกัน
# Build stage
FROM golang:1.18-alpine AS builder
WORKDIR /crud
COPY . .
RUN go mod download
EXPOSE 2565
RUN go build -o /test main.go
# Deploy stage
FROM alpine:latest
WORKDIR /
COPY --from=builder /test /test
EXPOSE 2565
USER nonroot:nonroot
ENTRYPOINT [ "/test" ]
เมื่อ build เรียบร้อยทั้งสองรูปแบบ มาดูผลลัพธ์กันดีกว่า
จะเห็นว่าการใช้ Multi-stage builds ช่วยลดขนาดให้ image ของเราอย่างมหาศาลเทียบกับแบบปกติ จาก 430 MB เป็น 16 MB พอเล็กแล้วก็สามารถนำไปใช้ต่อได้ง่ายมากขึ้นนั่นเอง
หวังว่าบทความนี้จะเป็นประโยชน์กับ Gopher และผู้ใช้ Docker ทุกคนกันนะครับ
Reference:
Optimizing Golang Docker images with multi-stage build | by Krishnadutt Panchagnula
Posted on May 29, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.