golang 與 docker 初體驗

Never12581發表於2020-04-06
  1. 學習docker 與 golang的相關知識,本處不贅述

  2. 編寫一個golang的測試用例main.go,如下:

    package main
    
    import (
        "github.com/gin-gonic/gin"
    )
    
    func main() {
    
        r := gin.Default()
        r.GET("/hello", hello)
        r.Run(":8080")
    }
    
    func hello(c *gin.Context) {
        c.JSON(200, gin.H{
           "message": "pong",
        })
    }
  3. 在同級目錄下建立對應Dockerfile

    # 使用最新版 golang 作為基礎映象
    FROM golang:latest AS builder
    #設定工作目錄,沒有則自動新建
    WORKDIR /go/src/
    #拷貝程式碼到當前
    COPY main.go /go/src/
    ## 編譯
    RUN go bulild main.go
    #執行服務
    CMD ["./main"]
  4. 建立映象docker build -t my-first .

  5. 不過會失敗,因為 在 go build 的過程中,在本映象中無法獲取對應的 github.com/gin-gonic/gin 依賴

  6. 所以我們採取以下的方案

    # 使用最新版 golang 作為基礎映象
    FROM golang:latest AS builder
    #設定工作目錄,沒有則自動新建
    WORKDIR /go/src/
    #拷貝程式碼到當前
    COPY main.go .
    
    # 獲取依賴
    RUN go get -d -v ./...
    RUN go install -v ./...
    
    ## 編譯
    RUN go bulild main.go
    #執行服務
    CMD ["./main"]
  7. 不大大概率還是失敗。。。因為有些東西會被牆住。。。

  8. 所以我們要採取粗暴的方式!將依賴直接打包進docker映象中。

    # 使用最新版 golang 作為基礎映象
    FROM golang:latest AS builder
    #設定工作目錄,沒有則自動新建
    WORKDIR /go/src/
    #拷貝程式碼到當前
    COPY main.go /go/src/
    COPY vendor/ /go/src/
    ## 編譯
    RUN go bulild main.go
    #執行服務
    CMD ["./main"]
  9. 本Dockerfile中,有一個上文沒提到過的vendor,其實該資料夾是存放的是當前服務的依賴。可以通過使用 go mod init,並且開啟 Vendoring mode ,此時sync 你的模組時,會在當前目錄下生成一個vendor資料夾

  10. 當然上述的打包出來的docker 映象太過於巨大了,可以減小映象體積,最終,生成的Dockerfile 如下:

    # 使用最新版 golang 作為基礎映象
    FROM golang:latest AS builder
    #設定工作目錄,沒有則自動新建
    WORKDIR /go/src/
    #拷貝程式碼到當前
    COPY main.go /go/src/
    COPY vendor/ /go/src/
    ## 編譯
    RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
本作品採用《CC 協議》,轉載必須註明作者和本文連結

from Never12581 azaizai@icloud.com

相關文章