使用Docker构建go程序

最近公司内部Go版本需要从1.7升级到最新版,涉及项目众多。为了正式环境自动构建系统能够兼容多版本方式构建,除了使用GVM方式之外,考虑到使用Docker Go程序构建容器更加的快速,不用每次版本切换时需要重新指定GOPATH。当然升级的目的,不仅仅的性能提升,第三方包兼容等,我们也会引入Go Moudule。特此记录此次Go升级实践。

构建镜像

我们使用官方镜像构建自己的镜像以便后续操作。

Dockerfile内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 最新版本构建容器
FROM golang:latest
MAINTAINER cheuk
# 创建构建目录
RUN mkdir /gobuilder
# SSH配置
RUN echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config
# 链接替换
RUN git config --global url."[email protected]:".insteadOf "http://gitlab.xxxx.com/"
# 工作目录
WORKDIR /gobuilder
# 环境变量配置
ENV GOPATH $GOPATH:/gobuilder
ENV GO111MODULE off
ENV GOPROXY ""
# 磁盘映射package
VOLUME ["/gobuilder","/go/src"]

SSH配置自动添加key到kown_hosts文件。Go在访问私有包的时候,请求协议为http,我们替换到ssh,这样能进行免密操作。

我们使用的最新版latest构建,创建并指定了我们的工作目录/gobuilder。运行构建:

1
docker build -t gobuilder
1
2
3
4
Sending build context to Docker daemon  2.048kB
........
........
Successfully tagged gobuilder:latest

构建成功,我们创建一个容器看一下:

1
docker run --rm -it gobuilder

使用参数-it我们进入交互模式,--rm退出的自动删除容器。查看下go版本:

1
2
root@3384acdd03c8:/gobuilder# go version
go version go1.13.1 linux/amd64

退出,我们映射我们的go 包文件内容到容器,启动容器:

1
docker run --rm -it -v ~/go/src/:/go/src gobuilder

-v将本机目录~/go/src/映射到容器中的/go/src目录。查看下目录下内容

1
ls /go/src/

可以看到Go已经映射到容器。同理可以映射需要构建的项目到容器 , 并运行构建

一键构建脚本

我们不能每次构建输入这一大串,我们写成一个脚本执行:

1
2
3
4
5
6
#!/bin/bash
docker run --rm -it \
-v $GOPATH/src:/go/src \
-v $(pwd):/gobuilder \
-v ~/.ssh/:/root/.ssh
gobuilder /bin/sh -c 'go mod download && go build '"$*"

这里我们映射了ssh的证书目录,这样可以共用已配置好的git正式。将脚本保存到$GOPATH/bin/gobuilder,修改执行权限

1
chmod +x $GOPATH/bin/gobuilder

OK,我们可以在项目目录使用我们的构建脚本了

1
gobuilder -o pack