Sebelumnya saya membahas cara men-deploy aplikasi golang ke Docker container, namun permasalahannya adalah ukuran berkas image dockernya terlalu besar sampai 265MB, itupun telah menggunakan base image golang yang menggunakan alpine linux.
hal yang paling menantang dalam membuat sebuah images adalah membuat ukuran images tetap ramping, pada server produksi kita hanya perlu menjalankan aplikasi dan menyertakan apa yang dibutuhkan untuk menjalankan aplikasi itu, pada golang kita hanya perlu menjalankan berkas binary dari hasil compile program golang, jadi kita tidak membutuhkan go terpasang pada container, lain halnya pada server yang digunakan untuk pengembangan atau staging kita perlu menambahkan semua hal yang dibutuhkan untuk membuat aplikasi tersebut
untungnya pada Docker versi 17.05 ke atas memudahkan dalam melakukan hal ini, pada versi 17.05 dikenalkan fitur baru yang bernama multi-stage build, dengan multi-stage build kita bisa menggunakan statemen FROM lebih dari 1, dan setiap FROM bisa menggunakan base image yang berbeda, dan setiap statemen FROM dipanggil menandakan pembuatan image pada stage baru, anda juga bisa dengan mudah menyalin artifacts dari satu stage ke stage lain,
berikut contoh Dockerfile dari multi-stage build
FROM golang:1.10.5-alpine3.8 as builder COPY main.go /app/ WORKDIR /app RUN go build -o main . FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /app/main . EXPOSE 8000 CMD ["./app"]
bisa kita lihat pada intruksi di atas pada stage pertama saya menggunakan base image golang:1.10.5-alpine3.8, menyetel alias dengan builder, menyalin program go ke direktori /app, menyetel ruang kerja di direktori /app dan terakhir meng-compile program go.
dan pada stage kedua menggunakan base image alpine:latest, memasang ca-certificates dengan parameter –no-cache, menyetel ruang kerja ke /root, menyalin program hasil compile dari stage pertama dengan alias builder, meng-expose port 8000 dan yang terakhir menjalankan program tersebut
lalu kita coba bangun dengan perintah docker build
$ sudo docker build -t taufik/go-multi-stage:1.0 . Sending build context to Docker daemon 7.68kB Step 1/10 : FROM golang:1.10.5-alpine3.8 ---> 2f577258bd10 Step 2/10 : COPY main.go /app/ ---> Using cache ---> b661115d9e4c Step 3/10 : WORKDIR /app ---> Using cache ---> 69bbcb8e2f63 Step 4/10 : RUN go build -o main . ---> Using cache ---> 40e181950a11 Step 5/10 : FROM alpine:latest ---> 196d12cf6ab1 Step 6/10 : RUN apk --no-cache add ca-certificates ---> Using cache ---> 84aa8025853a Step 7/10 : WORKDIR /root/ ---> Using cache ---> f073bc21585c Step 8/10 : COPY --from=0 /app/main . ---> Using cache ---> 2900666b24d8 Step 9/10 : EXPOSE 8000 ---> Running in 0fd6993cabc5 Removing intermediate container 0fd6993cabc5 ---> 4aab701bd473 Step 10/10 : CMD ["./app"] ---> Running in a657c13341a8 Removing intermediate container a657c13341a8 ---> 5e18d715b8cb Successfully built 5e18d715b8cb Successfully tagged taufik/go-multi-stage:1.0
dan sekarang bisa kita lihat ukuran image yang sekarang jauh lebih lebih ramping
REPOSITORY TAG IMAGE ID CREATED SIZE taufik/go-multi-stage 1.0 5e18d715b8cb About a minute ago 11.6MB