网上搜索的大都是(我看到的全都是)把golang项目的源码包全部copy进容器内,然后在容器内RUN go build,这种方案显然不如只COPY 二进制文件到容器内的方案。
一、交叉编译
golang支持交叉编译,在一个平台上生成另一个平台的可执行文件。
Mac下编译linux和windows平台:
CGO_ENABLE=0 GOOS=linux GOARCH=amd64 go build main.go
CGO_ENABLE=0 GOOS=windows GOARCH=amd64 go build main.goLinux下编译Mac和windows平台:
CGO_ENABLE=0 GOOS=darwin GOARCH=amd64 go build main.go
CGO_ENABLE=0 GOOS=windows GOARCH=amd64 go build main.goWindows下编译Mac和Linux平台:
SET CGO_ENABLE=0
SET GOOS=darwin
SET GOARCH=amd64
go build main.go
SET CGO_ENABLE=0
SET GOOS=linux
SET GOARCH=amd64
go build main.go二、实例
- 目录结构
main.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:8080") // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
build.sh (这里的交叉编译参数是关键,我的宿主机是Mac,如果不加交叉编译参数,那么生成的二进制文件copy 进入容器也无法正常运行)
#!/bin/sh
CGO_ENABLE=0 GOOS=linux GOARCH=amd64 go build -o gin_docker main.go
docker build -t gin_docker .Dockerfile 这里只需要把编译的结果gin_docker copy进去即可。这里有一点疑问是,如果已经是可执行文件,那么是否还需要golang:alpine的基础镜像了?大佬们指点下
FROM golang:alpine
WORKDIR /gin_docker
COPY gin_docker ./gin_docker
EXPOSE 8080
ENTRYPOINT ["./gin_docker"]start.sh
#!bin/bash
sh build.sh
docker run -p 8080:8080 -d gin_docker每次修改万代码,要启动只需要执行
sh start.sh
即可。
当然,这里只是镜像的构建,后续将构建的镜像推导镜像仓库,k8s 自动部署对应的镜像就是后续流程了。