packagemainimport("net/http""gin/bar""gin/foo""github.com/gin-gonic/gin")funcmain(){r:=gin.Default()r.GET("/ping",func(c*gin.Context){c.JSON(http.StatusOK,gin.H{"message":"pong",})})r.GET("/ping2",func(c*gin.Context){c.JSON(http.StatusOK,gin.H{"message":"pong2",})})r.GET("/ping100",func(c*gin.Context){c.JSON(http.StatusOK,gin.H{"message":foo.Foo(),})})r.GET("/ping101",func(c*gin.Context){c.JSON(http.StatusOK,gin.H{"message":bar.Bar(),})})r.Run()// listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")}
FROMgolang:1.14-alpineLABELmaintainer="Bo-Yi Wu <appleboy.tw@gmail.com>"RUN apk add bash ca-certificates git gcc g++ libc-devWORKDIR/app# Force the go compiler to use modulesENVGO111MODULE=on
# We want to populate the module cache based on the go.{mod,sum} files.COPY go.mod .COPY go.sum .RUN go mod downloadCOPY main.go .COPY foo/foo.go foo/COPY bar/bar.go bar/ENVGOOS=linux
ENVGOARCH=amd64
RUN go build -o /app -v -tags netgo -ldflags '-w -extldflags "-static"' .CMD ["/app"]
可以看到如果 go.mode 跟 go.sum 如果沒有任何變動,基本上 go module 檔案自然就可以透過 docker cache layer 處理。但是每次只要程式碼有任何異動,最後的 go build 會從無到有編譯,請看底下結果:
# syntax = docker/dockerfile:experimentalFROMgolang:1.14-alpineLABELmaintainer="Bo-Yi Wu <appleboy.tw@gmail.com>"RUN --mount=type=cache,target=/var/cache/apk apk add bash ca-certificates git gcc g++ libc-devWORKDIR/app# Force the go compiler to use modulesENVGO111MODULE=on
# We want to populate the module cache based on the go.{mod,sum} files.COPY go.mod .COPY go.sum .RUN --mount=type=cache,target=/go/pkg/mod go mod downloadCOPY main.go .COPY foo/foo.go foo/COPY bar/bar.go bar/ENVGOOS=linux
ENVGOARCH=amd64
RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build go build -o /app -v -tags netgo -ldflags '-w -extldflags "-static"' .CMD ["/app"]