เนื่องจาก Go สามารถ build โปรแกรมเป็น static binary ที่ไม่ต้องอาศัย shared library ตอน runtime ทำให้เราสามารถ build Go แล้วเอา binary ที่ได้ไปสร้าง Docker image จาก base scratch ได้ ทำให้ได้ image ที่ size เล็กๆเท่าที่จะเล็กได้
ทีนี้เนื่องจาก Docker สามารถทำ Dockerfile แบบ multiple stages ทำให้เราสามารถเขียน Dockerfile ทั้งเพื่อให้ build Go เป็น binary แล้วก็สร้าง image สำหรับ run binary นั้นได้ในไฟล์เดียวได้
ซึ่ง Dockerfile ที่รวมสอง stage เอาไว้แล้วมีแค่นี้
FROM golang:1.14.4 AS builder
ENV GO111MODULE=on \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64
WORKDIR /app
COPY . .
RUN go build \
-trimpath \
-ldflags "-s -w -extldflags '-static'" \
-o service
FROM scratch
WORKDIR /app
COPY --from=builder /app/service .
CMD ["./service"]
หลักๆคือเซต env CGO_ENABLED=0
เพื่อบอกว่าจะ build โดยไม่ใช้ CGO เลย (แน่นอนถ้าเราจำเป็นต้องใช้ package สำหรับ CGO จริงๆก็จะใช้ base scratch ไม่ได้) ส่วน option ตอน build ที่ใส่ -ldflags "-s -w -extldflags '-static'"
เพื่อให้ binary ที่ได้ตัดบางฟีเจอร์สำหรับ debug ออกจาก binary ทำให้ได้ binary size ที่เล็กลง
ส่วน stage สุดท้ายคือเอา binary ที่ได้จาก stage builder มาใส่ใน image ที่ base จาก scratch แล้วก็สั่งรันแค่นั้น
Top comments (0)