在 docker build 中缓存“go get”

2024-04-29

我想将 golang 单元测试封装在 docker-compose 脚本中,因为它依赖于多个外部服务。我的应用程序有很多依赖项,因此需要一段时间go get.

如何以允许构建 docker 容器的方式缓存包,而无需每次要测试时下载所有依赖项?

我的 Dockerfile:

FROM golang:1.7

CMD ["go", "test", "-v"]

RUN mkdir -p /go/src/app
WORKDIR /go/src/app

COPY . /go/src/app
RUN go-wrapper download
RUN go-wrapper install

每次我想运行单元测试时我都会运行docker-compose up --build backend-test在以下脚本上:

version: '2'
services:
  ...
  backend-test:
    build:
      context: .
      dockerfile: Dockerfile
    image: backend-test
    depends_on:
      ...

But now go-wrapper download每次我想运行测试时都会调用它,并且需要很长时间才能完成。

解决方案?提前致谢!


我个人使用govendor https://github.com/kardianos/govendor。它根据 golang 供应商约定将您的依赖项保存在项目内的供应商目录中。这仍然需要在构建时复制到您的 docker 映像中。

但有充分的理由不供应商。例如,当您构建 pkg 时,您不应该供应商。当您有不同的 pkg 使用不同版本的依赖项时,事情就会变得混乱。这可以通过仅供应可执行文件来解决。

因此,如果您有充分的理由不供应商,您可以分开几个步骤。 将它们按正确的顺序排列会加快速度。

您可以创建一个 shell 脚本(get.sh) 和一些go get依赖命令。 (你可以将它们放入你的 Dockerfile 中,但它们有行数限制)

go get github.com/golang/protobuf/proto
go get github.com/pborman/uuid
go get golang.org/x/net/context
go get golang.org/x/net/http2
go get golang.org/x/net/http2/hpack

然后在 Dockerfile 中首先复制并执行 shell 脚本。 每次更新 get.sh 时,它都会完全重建。它仍然运行got get ./...以确保所有依赖项都存在。但如果所有内容都添加到get.sh脚本,您将获得相当大的速度提升。

FROM golang:1.6

RUN mkdir -p /go/src/app

COPY get.sh /go/src/app

WORKDIR /go/src/app

RUN bash get.sh

COPY . /go/src/app

RUN go get ./...

CMD go test -v

总的想法是,您要经常更改 Dockerfile 中较低的内容,而顶部的内容则相当恒定。即使您必须添加一两个命令。 Docker 会逐行进行,直到找到需要重建的内容,然后也会执行此后的每一行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 docker build 中缓存“go get” 的相关文章

随机推荐

  • x86 平台中的 KVM 影子页表处理

    据我了解 在没有硬件支持来宾虚拟到主机物理地址转换的处理器上 KVM 使用影子页表 当来宾操作系统修改其页表时 会构建和更新影子页表 硬件中有没有专门的指令 以x86为参考 来修改页表 除非有特殊说明 否则不会对VMM 造成陷阱 Linux
  • 具有多字符替换的字符串组合(产生返回Java的替代重写)[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 还有另一篇 Stack Overflow 帖子是为与车辆登记号相关的算法创建的 根据输入的车牌 例如ABC123 和列表 替换值 例如
  • MQ (Websphere 7) 将消息持久保存到文件系统

    我如何设置 MQ 以便收到的每条消息都立即写入文件系统 我有 红皮书 但至少需要有人至少指出书中的章节或标题来弄清楚 我们是一家 NET 商店 我已经通过 API 编写了 C 来读取队列 目前我们使用 BizTalk MQ 适配器 我们的最
  • Crystal lang 进程是否可以更改其用户(euid/uid)?

    如果 Crystal 语言进程以 root 身份运行 是否可以将其 euid uid 更改为其他内容 例如 old euid old ui Process euid Process uid Process euid someone else
  • ipad 2相机支持检测

    我有一个使用以下宏的应用程序 define IS IPAD UIDevice currentDevice respondsToSelector selector userInterfaceIdiom UIDevice currentDevi
  • 将 Android 应用程序部署到手机:错误:[install_itemfolder_01] 错误 1 ​​Windows

    我已经安装了我可能需要的所有组件 我已经上网两天了 但找不到这个问题的答案 我检查了我的 apache ant javac java JRE JDK Qt 变量一切正常 Qt 喜欢我的所有设置 除了当我尝试将应用程序部署到模拟器或设备时出现
  • 在 bash 中传递多个数组作为参数

    我已经成功地能够调用单个数组作为参数 但在传递多个数组时遇到问题 这是我到目前为止所拥有的 calling function array1 1 2 3 4 array2 a b c d array3 called function arra
  • 通过 Hyperledger Composer 中的交易创建资产

    在创建任何asset or 参与者需要检查一些条件就像 如果 那么 否则 在某些领域 是否可以创建Asset or 参加者通过交易 对的 这是可能的 我在我的网络中做了同样的事情 通过交易创建资产并应用您需要的任何规则 事务从 lib 中的
  • Google 组织结构图数据溢出到 div 之外

    我在一个项目中使用 Google Org 图表 图表的内容在包含的 div 之外流动 该 div 在下面以红色突出显示 我希望图表的节点能够移动到下一行 以防它流到 div 之外 爱丽丝将移动到下一行 数据将继续 See my 在这里摆弄
  • 小写表名错误

    我正在尝试设置lower case table name价值2 因为它是 Windows 服务器 但是当我启动 MySQL Workbench 并连接到我的服务器时 出现以下错误 服务器所在的系统不能正确支持所选的lower case ta
  • 具有默认值的 Asp.net webapi 枚举参数

    我有一个控制器 HttpGet RoutePrefix api products productId public HttpResponseMessage Products int productId TypeEnum ptype Type
  • 离开页面时 JQuery Ajax 错误

    我使用以下代码将数据从服务器异步提取到客户端 错误块中的警报报告服务器上发生的错误 但是 如果用户在调用过程中离开页面 该块也会被触发并抛出一个空的警报容器 有什么方法可以更优雅地处理用户离开页面的情况 即在离开之前不抛出空警报 也许可以通
  • 当加载图标且 tk.mainloop 位于线程中时,Tkinter 会锁定 Python

    这是测试用例 import Tkinter as tk import thread from time import sleep if name main t tk Tk thread start new thread t mainloop
  • 如何更改 Rx Builder 实现来修复堆栈溢出异常?

    我正在尝试提出一个 Rx Builder 以在 F 计算表达式语法中使用反应式扩展 我该如何修复它 以免堆栈崩溃 就像下面的 Seq 例子一样 是否有计划提供 RxBuilder 的实现作为响应式扩展的一部分或作为 NET Framewor
  • <%= foo %> 和 ${ foo } 之间的区别

    第一次在 JSP 中编码 我需要将变量的值呈现为 HTML 看起来有多种方法可以做到这一点 它们之间有什么区别 假设我有一个名为foo and foo 这 使用老式的输出小脚本这是十年来一直灰心丧气 https stackoverflow
  • 如何从字符串读取 NumPy 二维数组?

    如何从字符串中读取 Numpy 数组 取一个像这样的字符串 0 5544 0 4456 0 8811 0 1189 并将其转换为数组 a from string 0 5544 0 4456 0 8811 0 1189 where a成为对象
  • 我可以为 XPath 中缺失的标签创建一个值吗?

    我有一个使用 XPath 从 XML 文件中提取数据的应用程序 如果该 XML 源文件中的节点丢失 我想返回值 N A 很像 Oracle NVL 函数 问题在于该应用程序不支持 XSLT 我想使用 XPath 和单独使用 XPath 来完
  • Spring MVC 配置启用

    我正在从头开始建立一个项目 目前我正在配置Spring MVC 4 1 5使用java配置 整个应用程序正在 tomcat gradle 插件上运行 有人可以解释一下为什么我需要对班级进行以下调用DefaultServletHandlerC
  • 作为依赖项和不同的 publicKeyToken 共享时 RestSharp 错误

    使用来自的 APIDocusign Twilio and Auth0 全部 3 个都有RestSharp dll作为依赖 如果我使用RestSharp dll包含在Docusign包裹 Docusign效果很好但是Auth0 and Twi
  • 在 docker build 中缓存“go get”

    我想将 golang 单元测试封装在 docker compose 脚本中 因为它依赖于多个外部服务 我的应用程序有很多依赖项 因此需要一段时间go get 如何以允许构建 docker 容器的方式缓存包 而无需每次要测试时下载所有依赖项