天天看點

gin web架構docker多階段建構實戰

準備項目

初始化一個項目

# mkdir demobuild
# cd demobuild/
# go mod init gindemo
go: creating new go.mod: module gindemo      

編寫代碼gindemo.go

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })

    r.Run("0.0.0.0:9091") // listen and serve on 0.0.0.0:8080
}      

嘗試運作

沒運作成功,提示需要安裝gin

# go run gindemo.go
gindemo.go:3:8: no required module provides package github.com/gin-gonic/gin; to add it:
    go get github.com/gin-gonic/gin      

安裝依賴

# go get github.com/gin-gonic/gin
go get: added github.com/gin-gonic/gin v1.7.4      

再次運作

# go run gindemo.go
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
[GIN-debug] Listening and serving HTTP on 0.0.0.0:9091      

多階段建構

編寫Dockerfile

FROM golang:1.17 as build

WORKDIR /go/src/gindemo

COPY . .

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOPROXY=https://goproxy.cn,direct go build -ldflags="-w -s" -o gindemo .


FROM ubuntu:18.04
WORKDIR /usr/local/demo
COPY --from=build /go/src/gindemo/gindemo .
EXPOSE 9091
CMD ["./gindemo"]      

檢視目錄結構

# tree
.
|-- Dockerfile
|-- gindemo.go
|-- go.mod
`-- go.sum

0 directories, 4 files      

執行建構鏡像

如果沒有多階段建構,你的操作可能如下:

  1. 在本地把go程式編譯好,再通過docker的方式拷貝到容器鏡像中,那麼本地環境是存在差異的
  2. 在容器鏡像中,先是安裝go環境,然後配置go可執行檔案環境變量,最後編譯,強耦合在一起了
# docker build . -t morebuild:test      

檢測鏡像是否建構成功

# docker images|grep morebuild
morebuild                                              test      4a0218330261   25 seconds ago      69.5MB      

項目運作

運作容器

docker run -it -d -p 9091:9091 morebuild:test      

檢視容器内部

45f54為容器運作部分ID

# docker exec -it 45f54 bash
root@45f541ce524f:/usr/local/demo# pwd
/usr/local/demo
root@45f541ce524f:/usr/local/demo# ls
gindemo
root@45f541ce524f:/usr/local/demo# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 06:13 pts/0    00:00:00 ./gindemo
root        11     0  0 06:13 pts/1    00:00:00 bash
root        23    11  0 06:13 pts/1    00:00:00 ps -ef      

curl通路

curl http://127.0.0.1:9091/ping      

檢視容器日志

# docker logs -f 45f54
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
[GIN-debug] Listening and serving HTTP on 0.0.0.0:9091
[GIN] 2021/10/29 - 06:23:43 | 200 |      58.471µs |      172.17.0.1 | GET      "/ping"      

至此已經示範完畢了