Taufik Mulyana
Taufik Mulyana
Linux System Administrator, Interested in Linux, Cloud, Containers
September 20, 2018 3 min read

Mengoptimalkan Docker Image dengan Multi Stage Build

Mengoptimalkan Docker Image dengan Multi Stage Build

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