2 Cara Untuk Menjalankan Golang App Dengan Docker

Lagi cari cara untuk menjalankan aplikasi Golang dengan docker? Baca post ini. Kita akan mencoba 2 cara untuk menjalankan aplikasi golang dengan docker. Kamu bisa menentukan yang mana yang lebih cocok untukmu.

Untuk menjalankan go app dengan docker, kita perlu membuat sebuah docker container. Kemudian jalankan container tersebut dengan resource-resource yang diperlukan. Tapi sebelum menyentuh docker, tentu saja kita perlu aplikasi golang nya dulu.

The Go application

Ini adalah web server sederhana yang akan kita gunakan.

package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()

    r.HandleFunc("/get_city", cityHandler)

    fmt.Println("listening..")
    http.ListenAndServe(":5005", r)
}

func cityHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte(`{"city":["jakarta","bandung","bandar lampung"]}`))
}

Untuk membuat sebuah docker container, kita perlu sebuah Dockerfile.
Buat sebuah file bernama Dockerfile di root directory dari aplikasi go mu.

Dockerfile golang root

Seperti yang dituliskan di awal, kita akan mencoba 2 metode untuk menjalankan go app di docker. Sekarang kita coba cara pertama.

Method 1: Build Go app binary in docker

Pada metode ini, kita copy source code kita ke container. Kemudian ambil library vendor dan build aplikasinya di dalam docker. Kita menggunakan multi-staged build untuk menghilangkan source code di image hasilnya. Jadi walaupun source code di copy di awal, image hasilnya hanya akan berisi binary dari aplikasi nya. Ini bisa mengurangi size dari image secara signifikan.
Berikut ini adalah Dockerfile untuk metode ini.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
FROM golang:1.15.8-alpine AS builder
WORKDIR /build
# Copy our go codes to workdir
COPY . .

ENV CGO_ENABLED=0 
RUN go mod vendor \
    && go build -o myapp .

# Build from scratch
FROM scratch
COPY --from=builder /build/myapp /
ENTRYPOINT ["/myapp"]

Langkah pertama adalah builder, kita gunakan image golang:1.15.8-alpine sebagai base image dari container kita. Kamu bisa ubah Go version nya jika ingin menggunakan versi lain. Stage ini kita beri nama builder seperti yang dapat dilihat pada line pertama. Pada line 4, kita copy semua source code ke container. Jika ingin mengeksklude sesuatu seperti folder vendor, kita dapat taro di file .dockerignore. Kemudian kita ambil library vendor yang dibutuhkan dan build aplikasi pada line berikutnya. Saya gunakan go mod pada contoh di sini. Bagian ini perlu diubah apabila menggunakan tool selain go mod.

Stage selanjutnya dimulai dari line 11. Kita buat container dari scratch karena kita cuma butuh binary dari aplikasi kita untuk dijalankan. Jadi kita copy hanya binary nya dari stage builder sebelumnya. Entrypoint menentukan aplikasi yang akan dijalankan ketika container berjalan, yaitu aplikasi Go kita.

Gunakan command ini untuk build image.

docker build -t godocker .

Setelah itu, kita bisa melihat image nya di daftar image dengan command docker images or docker image ls.

Untuk membuat dan menjalankan container menggunakan image, jalankan command berikut.

docker run -p 5005:5005 --rm godocker
Option -p 5005:5005 adalah untuk menghubungkan port container 5005 ke port host 5005. Ini berarti, mengirim request ke port host tersebut akan diteruskan ke container.
Option --rm untuk menghapus container apabila container di stop.

Sekarang aplikasi golang mu sudah berjalan di docker. Untuk melihatnya, bisa menggunakan command docker ps atau docker container ls.

docker ps

Itu cara menjalankan aplikasi go di docker metode 1. Sekarang kita coba metode 2.

Methods 2: Copy the binary only

Pada metode ini, binary di build di environment di luar docker, seperti environment local kita. Kita hanya mengcopy binary aplikasi yang sudah di build ke docker. Tapi kita perlu set variable CGO_ENABLED=0 dan GOOS=linux ketika build aplikasi kita supaya bisa jalan di docker container. Kita bisa menggunakan tool seperti Makefile untuk mempermudah menjalankan command. Berikut ini adalah contoh command untuk build aplikasi Go.

CGO_ENABLED=0 GOOS=linux go build -o myapp

Ini adalah Dockerfile untuk metode ini.

FROM scratch
COPY myapp /
ENTRYPOINT ["/myapp"]

Ini mirip dengan stage terakhir dari metode 1. Beda nya adalah kita mengcopy binary dari computer kita, bukan dari stage sebelumnya di container.

Kesimpulan

Kita sudah mencoba 2 metode untuk menjalankan Golang dengan docker. Kamu bisa menentukan metode mana yang paling cocok dengan kebutuhanmu. Atau mungkin kamu punya metode sendiri selain 2 ini, misalkan pull source code dari git di dalam docker. Leave a comment.


See also