Skip to content

DockerFile go分步构建模板

以下是我在项目中常用与构建docker镜像的模板

注意事项:

  1. 使用时需要手动指定复制的配置文件位置
  2. 容器运行的scratch为最小的基础镜像,并没有Shell,调试工具。如果需要进入容器操作,可以使用Alpine,或者更大的CentOS,Ubuntu。
  3. 在软件开发阶段建议使用CentOS,Ubuntu作为运行镜像,能避免很多麻烦。在项目稳定之后可以再考虑优化Docker镜像的体积。

特点:

  1. 与宿主环境无关,软件在golang:latest当中构建。构建结束后将产物复制到较小的scratch镜像中运行。
  2. 使用goproxy.cn加速依赖下载
  3. 设置时区为上海(Asia/Shanghai)
  4. 已经添加ca证书,避免服务端请求 https 时出现 错误: x509: certificate signed by unknown authority
dockerfile
  # 构建:使用golang:latest构建
  FROM golang:latest as build
  # 容器环境变量添加
  ENV GO111MODULE=on
  ENV GOPROXY=https://goproxy.cn,direct
  # 设置当前工作区
  WORKDIR /go/release
  # 把全部文件添加到/go/release目录
  COPY . .
  # 编译: 把main.go编译为可执行的二进制文件, 并命名为app
  RUN GOOS=linux CGO_ENABLED=0 GOARCH=amd64 go build -ldflags="-s -w" -installsuffix cgo -o app main.go
  # 运行: 使用scratch作为基础镜像
  FROM scratch as prod
  # 在build阶段, 复制时区配置到镜像的/etc/localtime
  COPY --from=build /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  # 在build阶段, 复制ca证书到镜像
  COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
  # 在build阶段, 复制./app目录下的可执行二进制文件到当前目录
  COPY --from=build /go/release/app /
  # 在build阶段, 复制yaml配置文件到当前目录, 此处需要注意调用该配置文件时使用的相对路径, main.go在当前目录下执行
  COPY --from=build /go/release/config.yaml /
  EXPOSE 80
  # 启动服务
  CMD ["/app"]

使用scratch基础镜像的Docker容器中程序出现 错误 x509: certificate signed by unknown authority

这个错误是由于scratch镜像中没有/etc/ssl/certs/ca-certificates.crt

原因

当操作系统建立TLS连接时(通过HTTPS向Web服务或API发出请求),远程服务器会向我们传输其证书。通常,该证书已由知名证书颁发机构(CA)签名。操作系统需要使用由CA公布的文件验证。即为/etc/ssl/certs/ca-certificates.crt

解决

构建镜像的时候将证书从其他镜像中复制

dockerfile
COPY --from=alpine /etc/ssl /etc/ssl

或者

dockerfile
COPY --from=alpine /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt

对于容器,可以通过

shell
docker cp /etc/ssl/certs/ca-certificates.crt 容器id:/etc/ssl/certs/ca-certificates.crt

命令复制宿主机证书到容器内