- Published on
如何将Golang服务构建为Docker镜像
- Authors
- Name
- houyw
- @Luckydog_H
前言
这篇文章将会说明我是如何使用多阶段 Dockerfile 构建适用于生产环境的 Go 服务 Docker 镜像。本文涵盖了创建精简、高效 Docker 镜像的详细步骤,用于部署 Go 应用程序。
代码实例
Dockerfile
# 第一步:安装依赖并编译
FROM golang:latest as builder
LABEL Author="houyw<1327603193@qq.com>" Version="1.0" Description="build image for hserver"
# 启用 Go modules 并设置 Go proxy
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn,direct
WORKDIR /go/cache
ADD go.mod .
ADD go.sum .
RUN go mod download
WORKDIR /go/release
ADD . .
RUN GOOS=linux CGO_ENABLED=0 go build -ldflags="-w -s" -o hserver ./main.go
# 第三步:构建最终生产镜像
FROM scratch as prod
COPY /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY /go/release/hserver /
COPY /go/release/templates /templates
COPY /go/release/assets /assets
COPY /go/release/config.json /config.json
COPY /go/release/log/gin.log /log/gin.log
ENV GIN_MODE=release \
PORT=8080
EXPOSE 8080
CMD ["/hserver"]
Dockerfile详解
- 第一步:构建器阶段
该阶段使用官方的golang:latest
镜像来编译 Go 应用程序。通过设置GO111MODULE
和GOPROXY
,确保所有依赖项都能可靠下载。随后,使用优化参数编译应用程序,生成最小化的二进制文件。
FROM golang:latest as builder
LABEL Author="houyw<1327603193@qq.com>" Version="1.0" Description="build image for hserver"
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn,direct
WORKDIR /go/cache
ADD go.mod .
ADD go.sum .
RUN go mod download
WORKDIR /go/release
ADD . .
RUN GOOS=linux CGO_ENABLED=0 go build -ldflags="-w -s" -o hserver ./main.go
- 第二步:生产镜像阶段
该阶段继承自scratch
镜像,这是一个空白镜像。只需从前上个阶段复制编译后的二进制文件和必要文件即可。最终生成的镜像非常小,仅包含运行 Go 服务所需的内容。
FROM scratch as prod
# 复制时区文件
COPY /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# 复制编译后的二进制文件和一些资源文件,如 模板、静态资源等
COPY /go/release/hserver /
COPY /go/release/templates /templates
COPY /go/release/assets /assets
COPY /go/release/config.json/config.json
COPY /go/release/log/gin.log /log/gin.log
# 设置环境变量和端口
ENV GIN_MODE=release \
PORT=8080
EXPOSE 8080
# 启动服务
CMD ["/hserver"]
构建和运行镜像
构建 Docker 镜像后,可以使用以下命令运行它:
docker build -t hserver:latest .
docker run -d --name hserver -p 8080:8080 hserver:latest
关于多阶段构建优势的一些
- 减少镜像大小: 仅将必要的文件复制到最终镜像中,保持镜像精简,从而加快部署速度并降低存储成本。
- 安全性: 更小的镜像表面积减少了潜在的漏洞。
- 效率: 使用精简的镜像进行构建和部署,提高了性能和启动速度。
总结
通过使用多阶段构建,我们可以将编译和运行所需的所有文件都放在同一个镜像中,从而简化了部署过程。
关于自动化部署,我依然使用了另外一篇文章中提到的方法(使用 GitHub Actions 自动构建和部署 Docker 镜像),只需将workflows稍加改动即可完成自动化的部署