Go dalam container

Kemarin ini nyobain bikin project go kecil-kecilan, intinya sih nyobain bikin koneksi ke mysql dan melakukan crud lah. Code nya saya ambil dari sini karena males bikin code sendiri.. wkwkwk.. (yes, i’m from wekaweka land)

kira-kira begini code main.go-nya

/*taken from here with minor edit*/package main

import (
_ "github.com/go-sql-driver/mysql"
"database/sql"
"fmt"
)

func main() {
db, err := sql.Open("mysql", "root:hai@/test?charset=utf8")
checkErr(err)

// insert
stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?")
checkErr(err)

res, err := stmt.Exec("astaxie", "telo", "2012-12-09")
checkErr(err)

id, err := res.LastInsertId()
checkErr(err)

fmt.Println(id)
// update
stmt, err = db.Prepare("update userinfo set username=? where uid=?")
checkErr(err)

res, err = stmt.Exec("astaxieupdate", id)
checkErr(err)

affect, err := res.RowsAffected()
checkErr(err)

fmt.Println(affect)

// query
rows, err := db.Query("SELECT * FROM userinfo")
checkErr(err)

for rows.Next() {
var uid int
var username string
var department string
var created string
err = rows.Scan(&uid, &username, &department, &created)
checkErr(err)
fmt.Println(uid)
fmt.Println(username)
fmt.Println(department)
fmt.Println(created)
}

// delete
stmt, err = db.Prepare("delete from userinfo where uid=?")
checkErr(err)

res, err = stmt.Exec(id)
checkErr(err)

affect, err = res.RowsAffected()
checkErr(err)

fmt.Println(affect)

db.Close()

}

func checkErr(err error) {
if err != nil {
panic(err)
}
}

Tapi selain bikin code itu, saya juga iseng bikin Dockerfile agar golang script itu jalan di container. Kira-kira Dockerfile-nya seperti ini

FROM alpine:3.5WORKDIR /appCOPY ./test /appENTRYPOINT ["/app/test]

Kemudian saya compile dengan nama output test

go build -o test main.go

Build & run docker-nya

// build docker image
docker build --no-cache -t connect-mysql:v1.0
// run docker image
docker run --net=host connect-mysql:v1.0

Dan akhirnya muncul error

standard_init_linux.go:178: exec user process caused "no such file or directory

Error ini terjadi karena binary go yang sudah compile itu tidak dapat di-execute oleh linux alpine. Ada beberapa solusi yang bisa diambil,

  1. Menggunakan flag CGO_ENABLED=0

Saat meng-compile code golang yang di dalamnya tidak menggunakan library C sama sekali, sebaiknya menggunakan flag ini, sehingga cara compile nya

env CGO_ENABLED=0 go build -o test main.go

Jika env development nya menggunakan windows, maka ada tambahan flag menjadi

env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o test main.go

2. Menggunakan image alpine untuk compile

Solusi ini menggunakan fitur multistage-build docker. Jadi yang perlu dilakukan adalah menggunakan image docker golang 1.8 yang sudah didalam alpine kemudian copy binary nya kedalam target image.

Tetapi sebelum itu, usahakan gunakan fitur vendor untuk golang agar semua dependency nya masuk ke dalam image tersebut dan tidak perlu melakukan go get didalam image builder. Untuk melakukan vendoring dependency, saya menggunakan govendor

govendor init
govendor add +external

Kemudian Dockerfile-nya berubah menjadi

FROM golang:1.8-alpine3.5 AS builder
WORKDIR /go/src/test-mysql-docker
COPY . .
RUN go build -o test main.go
FROM alpine:3.5
WORKDIR /app
COPY --from=builder /go/src/test-mysql-docker/test .
ENTRYPOINT ["/app/test"]

Solusi mana yang baik?

Kalau menurut saya sih tergantung selera. Untuk solusi nomor 1, mungkin lebih enak jika dimasukkan ke dalam Makefile. Contoh misal

.PHONY:allall: compile buildcompile:
CGO_ENABLED=0 go build -o test main.go
build:
docker build --no-cache -t connect-mysql:v1.0

Sehingga mudah saat melakukan operasi compile dan build nya. Problemnya adalah saat env development-nya berubah menggunakan windows atau osx misal, khususnya windows, karena jika di compile di windows maka jadinya adalah executable windows (file.exe), ga akan jalan di linux.

Untuk solusi nomor 2, tidak perlu melakukan compilasi di local, sehingga tidak masalah saat harus di compile di windows, linux, atau osx semua pasti jalan asal ada docker di host-nya.

)
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade