1. 前言

这几天在构建golang编写的web项目中,关于dockerfile编写的一些总结

可能是单纯我比较菜(大雾

由于go应用在go build之后会生成一个二进制文件,且Go宣称自己只需要Linux内核

大多数编程语言都依赖于解释器,VM和/或系统库

刚开始我按照常理思考,写出了如下的dockerfile, 但是最终docker build出来的镜像高达300多M, 这是由于golang这个基础镜像中的工具链及其依赖项(gitmercurial等)重达几百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,它是一个空的镜像,在临时基础镜像上运行的应用程序只能访问内核

至少在容器提供隔离的范围内

所以此时我们的思路是

  1. golang基础镜像下build出二进制文件
  2. 然后使用scratch作为运行时的基础镜像
  3. 并且将上一个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

go项目dockerfile最佳实践的更多相关文章

  1. 【原创】Docker实战 Dockerfile最佳实践&&容器之间通信

    官方最佳实践文档 https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#from Docker实战(三十) ...

  2. dockerfile 最佳实践及示例

    Dockerfile 最佳实践已经出现在官方文档中,地址在 Best practices for writing Dockerfiles.如果再写一份最佳实践,倒有点关公门前耍大刀之意.因此本篇文章是 ...

  3. 《容器高手实战: Dockerfile最佳实践》

    Dockerfile最佳实践一个容器对应一个进程一个Docker容器应该只对应一个进程,也就是一个Docker 镜像一般只包含一个应用的制品包(比如.jar). 在需要组合多个进程的场景,使用容器组( ...

  4. Dockerfile 最佳实践

    之前 一篇文章介绍 docker 的镜像基本原理和概念 ,主要介绍在编写 docker 镜像的时候一些需要注意的事项和推荐的做法. 虽然 Dockerfile 简化了镜像构建的过程,并且把这个过程可以 ...

  5. SpringBoot系列: Spring项目异常处理最佳实践

    ===================================自定义异常类===================================稍具规模的项目, 一般都要自定义一组异常类, 这 ...

  6. 编写 Dockerfile 最佳实践

    官方仓库虽然有数十万计的免费镜像,但大多数无法直接满足公司业务需求,这就需要我们自己去定制镜像了. Docker通过Dockerfile自动构建镜像,Dockerfile是一个包含用于组建镜像的文本文 ...

  7. Dockerfile最佳实践(一)

    1.使用缓存  Dockerfile的每条指令都会将结果提交为新的镜像,下一跳指令将会基于上一步指令的镜像的基础上构建,如果一个镜像存在相同的父镜像和指令(除了ADD),Docker将会使用镜像而不是 ...

  8. React项目的最佳实践

    项目代码 从零开始简书项目 ​ 从我第一次接触vue这个框架已经过了快一年的时间,陪伴我从前端小白到前端工程师,前端时间也是使用了 ts+vue这样的组合写代码,明显感觉vue与ts似乎没有产生比较好 ...

  9. vue项目缓存最佳实践

    需求 在开发vue的项目中有遇到了这样一个需求:一个视频列表页面,展示视频名称和是否收藏,点击进去某一项观看,可以收藏或者取消收藏,返回的时候需要记住列表页面的页码等状态,同时这条视频的收藏状态也需要 ...

随机推荐

  1. 十位大牛做出的web前端开发规范总结

    Web前端作为开发团队中不可或缺的一部分,需要按照相关规定进行合理编写(一部分不良习惯可能给自己和他人造成不必要的麻烦).不同公司不同团队具有不同的规范和文档.下面是根据不同企业和团队的要求进行全面详 ...

  2. 什么是jsp?

    1.什么是jsp? jsp就是java 服务器页面(java server page) 2.jsp有什么用? jsp的出现是为了解决Servlet页面显示方面的不足. 3.jsp的三种脚本: 4.js ...

  3. Docker可视化工具Portainer

    1 前言 从没想到Docker也有可视化的工具,因为它的命令还是非常清晰简单的.无聊搜了一下,原来已经有很多Docker可视化工具了.如DockerUI.Shipyard.Rancher.Portai ...

  4. 使用MWeb进行博客发布测试

    MWeb 是专业的 Markdown 写作.记笔记.静态博客生成软件,目前已支持 Mac,iPad 和 iPhone.MWeb 有以下特色: 软件本身: 使用原生的 macOS 技术打造,追求与系统的 ...

  5. 树形dp——三色二叉树

    题目描述 一棵二叉树可以按照如下规则表示成一个由0.1.2组成的字符序列,我们称之为"二叉树序列S": 0 该树没有子节点 1S1 该树有一个子节点,S1为其二叉树序列 1S1S2 ...

  6. CF3D Least Cost Bracket Sequence 题解

    题目 This is yet another problem on regular bracket sequences. A bracket sequence is called regular, i ...

  7. 洛谷P5774,可爱的动态规划。

    如此可爱的动态规划见过么? 相信各位都非常喜欢动态规划,那我就写一道可爱的动态规划的题解吧. 题目:https://www.luogu.com.cn/problem/P5774 题意: 题意“挺明白” ...

  8. ecs架构思考

    系统管理者, ecs本身要处理的是遍历, 遍历结构处理事情. 而不同的场景要处理的事务是不一样的, 所以系统是要动态增加或者减少的. 而实体代表着一个真正的对象, 对象本身是复杂的, 拥有多种属性的. ...

  9. 图文详解Prometheus监控+Grafana+Alertmanager告警安装使用

    一:前言 一个服务上线了后,你想知道这个服务是否可用,需要监控.假如线上出故障了,你要先于顾客感知错误,你需要监控.还有对数据库,服务器的监控,等等各层面的监控. 近年来,微服务架构的流行,服务数越来 ...

  10. C++求树子节点权重最大的和

    #include <iostream> #include <vector> using namespace std; int n; const int MaxN = 1e5; ...