Golang项目构建Docker镜像
使用Dockerfile文件构建镜像
在Go项目路径下,创建一个新的Dockerfile文件,即可根据Dockerfile中的指令来构建对应的docker镜像。
本文中,我的项目结构如下:
.
├── Template
└── webForm.go
编写Dockerfile
# 导入基础镜像golang:alpine
FROM golang:alpine AS builder
# 设置环境变量
ENV GO111MODULE=auto \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64 \
GOPROXY="https://goproxy.cn,direct"
# 创建并移动到工作目录(可自定义路径)
WORKDIR /build
# 将代码复制到容器中
COPY . .
# 将代码编译成二进制可执行文件,文件名为 WebApp
RUN go build -o WebApp .
# 移动到用于存放生成的二进制文件的 /dist 目录
WORKDIR /dist
# 将二进制文件从 /build 目录复制到这里
RUN cp /build/WebApp .
# 将项目用到的静态文件拷贝到镜像(如果没有可忽略该步骤)
COPY ./Template /dist/Template
# 声明服务端口
EXPOSE 9090
# 启动容器时运行的命令
CMD ["./WebApp"]
在终端移动到项目路径下,执行指令构建docker镜像
# goweb_app:v0为镜像名,可自行更改
docker build . -t goweb_app:v0
终端输出如下日志,即代表构建成功
Successfully built 6adbd92bed46
Successfully tagged goweb_app:v0
输入如下指令,启动镜像(端口号和镜像名根据自己的设置进行更改)
docker run -p 9090:9090 goweb_app:v0
可打开新终端,输入如下指令查看镜像
docker images
可以看到构建的镜像很大(我的高达300M),因为镜像包含了golang:alpine基础镜像。下面可以采用分阶段构建的方式优化。
分阶段构建docker镜像
上述构建方法中,会把基础镜像golang:alpine同时封装进去,而go应用在编译好以后可以不依赖编译器而运行。所以可以在项目编译以后构建一个不包含编译器的小镜像,然后从编译器中将编译好的二进制文件取出来进行封装,这样就可以构建不包含编译器的小镜像文件。
# 导入基础镜像golang:alpine
FROM golang:alpine AS builder
# 设置环境变量
ENV GO111MODULE=auto \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64 \
GOPROXY="https://goproxy.cn,direct"
# 创建并移动到工作目录(可自定义路径)
WORKDIR /build
# 将代码复制到容器中
COPY . .
# 将代码编译成二进制可执行文件,文件名为 WebApp
RUN go build -o WebApp .
# 利用scratch创建一个小镜像
FROM scratch
# 从builder镜像中把/WebApp 拷贝到当前目录
COPY --from=builder /build/WebApp /
# 将项目用到的静态文件拷贝到镜像(如果没有可忽略该步骤)
COPY ./Template /Template
# 声明服务端口
EXPOSE 9090
# 启动容器时运行的命令
CMD ["/WebApp"]
同样的,在终端移动到项目路径下,执行指令构建docker镜像
# goweb_app:v0为镜像名,可自行更改
docker build . -t goweb_app:v0
终端输出如下日志,即代表构建成功
Successfully built 6adbd92bed46
Successfully tagged goweb_app:v0
输入如下指令,启动镜像(端口号和镜像名根据自己的设置进行更改)
docker run -p 9090:9090 goweb_app:v0
借助scratch创建的小镜像不包含编译器,因此很小(我的8M)。
注意:采用scratch方式构建的镜像不能使用sh指令
采用软件自动编写Dockerfile
借助goct工具可以实现Dockerfile的快速生成
首先安装一下工具
GOPROXY=https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest
移动到项目所在路径,直接执行指令,快速构建镜像
# webForm.go改为你自己的项目文件
goctl docker -go webForm.go
也可以用指定方式镜像分阶段构建镜像(此处以 scratch为例)
goctl docker -base scratch -go webForm.go
生产的Dockerfile文件如下
FROM golang:alpine AS builder
LABEL stage=gobuilder
ENV CGO_ENABLED 0
ENV GOPROXY https://goproxy.cn,direct
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk update --no-cache && apk add --no-cache tzdata
WORKDIR /build
ADD go.mod .
ADD go.sum .
RUN go mod download
COPY . .
RUN go build -ldflags="-s -w" -o /app/webForm webForm.go
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
ENV TZ Asia/Shanghai
COPY --from=builder /app/webForm /
COPY ./Template /Template
CMD ["/webForm"]
经试验,采用该方式可以生成一个完整的Dockerfile框架,但是不一定可以直接使用。我构建好以后,由于没有自动导入静态文件Template导致不可用,自行在Dockerfile中修改添加了静态文件即可。
采用该方式构建,文件中务必包含go.mod和go.sun文件
参考资料
链接: https://www.cnblogs.com/kevinwan/p/16033634.html
链接: https://juejin.cn/post/6899041488806936583