go项目dockerfile最佳实践
1. 前言
这几天在构建golang编写的web项目中,关于dockerfile编写的一些总结
可能是单纯我比较菜(大雾
由于go应用在go build
之后会生成一个二进制文件,且Go宣称自己只需要Linux内核
大多数编程语言都依赖于解释器,VM和/或系统库
刚开始我按照常理思考,写出了如下的dockerfile
, 但是最终docker build
出来的镜像高达300多M, 这是由于golang
这个基础镜像中的工具链及其依赖项(git
,mercurial
等)重达几百MB,而这一部分我们在运行的时候是不需要的
FROM golang:1.14
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn,direct \
GIN_MODE=release \
PORT=80
WORKDIR /app
COPY . .
RUN go build .
EXPOSE 80
ENTRYPOINT ["./toc-generator"]
2. 不需要cgo情况下的最佳实践
docker有一个基本镜像叫做scratch,它是一个空的镜像,在临时基础镜像上运行的应用程序只能访问内核
至少在容器提供隔离的范围内
所以此时我们的思路是
- 在
golang
基础镜像下build出二进制文件 - 然后使用
scratch
作为运行时的基础镜像 - 并且将上一个stage build出来的
二进制文件
和它的相关依赖文件
copy到scratch下
所以我们现在的dockerfile
大概如下
# 打包依赖阶段使用golang作为基础镜像
FROM golang:1.14 as builder
# 启用go module
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn,direct
WORKDIR /app
COPY . .
# CGO_ENABLED禁用cgo 然后指定OS等,并go build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build .
# 由于我不止依赖二进制文件,还依赖views文件夹下的html文件还有assets文件夹下的一些静态文件
# 所以我将这些文件放到了publish文件夹
RUN mkdir publish && cp toc-generator publish && \
cp -r views publish && cp -r assets publish
# 运行阶段指定scratch作为基础镜像
FROM scratch
WORKDIR /app
# 将上一个阶段publish文件夹下的所有文件复制进来
COPY --from=builder /app/publish .
# 为了防止代码中请求https链接报错,我们需要将证书纳入到scratch中
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/cert
# 指定运行时环境变量
ENV GIN_MODE=release \
PORT=80
EXPOSE 80
ENTRYPOINT ["./toc-generator"]
3. 依赖cgo情况下的最佳实践
由于需要依赖cgo,所以我们使用scratch
无法满足需求,我们需要另外一个运行时基础镜像alpine
,看下dockerhub
官方的介绍,它也仅仅只有5MB大小
所以替换下基础镜像,我们的dockerfile
变成了如下的样子:
# 打包依赖阶段使用golang作为基础镜像
FROM golang:1.14 as builder
# 启用go module
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn,direct
WORKDIR /app
COPY . .
# 指定OS等,并go build
RUN GOOS=linux GOARCH=amd64 go build .
# 由于我不止依赖二进制文件,还依赖views文件夹下的html文件还有assets文件夹下的一些静态文件
# 所以我将这些文件放到了publish文件夹
RUN mkdir publish && cp toc-generator publish && \
cp -r views publish && cp -r assets publish
# 运行阶段指定scratch作为基础镜像
FROM alpine
WORKDIR /app
# 将上一个阶段publish文件夹下的所有文件复制进来
COPY --from=builder /app/publish .
# 指定运行时环境变量
ENV GIN_MODE=release \
PORT=80
EXPOSE 80
ENTRYPOINT ["./toc-generator"]
参考链接
https://baijiahao.baidu.com/s?id=1617163590078677512&wfr=spider&for=pc
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~