使用 Docker 容器化 Go 專案

環境

  • Go 1.13.4

建立專案

新增 main.go 檔:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import (
"fmt"
"net/http"
)

func index(w http.ResponseWriter, req *http.Request) {
fmt.Fprint(w, "Hello\n")
}

func main() {
http.HandleFunc("/", index)

http.ListenAndServe(":8090", nil)
}

容器化

新增 docker-compose.yaml 檔:

1
2
3
4
5
6
7
8
9
10
version: "3"

services:
app:
container_name: app
build:
context: .
dockerfile: Dockerfile
ports:
- "8090:8090"

新增 Dockerfile 檔:

1
2
3
4
5
6
7
8
9
FROM golang:latest

WORKDIR /app

COPY . .

RUN go build -o main .

ENTRYPOINT ./main

新增 .dockerignore 檔:

1
2
3
4
.git
.gitignore
Dockerfile
docker-compose.yaml

編譯並啟動容器:

1
docker-compose up -d --build

多階段建構

使用 Docker 的 multi-stage builds 可以將容器的建構過程拆分為不同的階段,以編譯出更小的映像檔。

修改 Dockerfile 檔:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# build stage
FROM golang:latest as builder

WORKDIR /app

COPY . .

RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

# final stage
FROM alpine:latest

RUN apk --no-cache add ca-certificates

WORKDIR /root

COPY --from=builder /app/main .

ENTRYPOINT ./main

編譯並啟動容器:

1
docker-compose up -d --build

映像檔從原來的 810MB 變為 13MB。

瀏覽網頁

前往 http://127.0.0.1:8090 瀏覽。

程式碼

參考資料