[英]Minimize `docker build` execution time inside Docker-in-Docker containers
我们在 Jenkins 中有几个“发布作业”,它们build
应用程序的 Docker 映像并将其push
送到 docker 注册表,更新各种文件中的项目版本,最后将发布标签推送到相应的 Git 存储库。 整个过程在一个隔离的 Docker-in-Docker容器中运行,这意味着每次执行这些 Jenkins 作业时,Docker 缓存完全空白。
简而言之: Jenkins 实例 --> 启动一个 DinD 容器 --> Git 存储库被克隆到 DinD 容器内 --> 具有多层的 Dockerfiles,包括正在构建的应用程序的实际构建过程 --> 将 docker 图像推送到registry --> 推送发布到 Git。
虽然这种隔离一方面有助于避免一些问题,但另一方面它使整个 docker 构建过程特别慢。
Docker pull 和 docker push 进程肯定会在一定程度上造成这种延迟,但这是一个我们无法处理 atm 的网络速度问题。
然而,这种迟到的另一个原因是,由于实际应用程序(maven 或 angular)是在一个“干净的”docker 容器中构建的,其中.m2或node_modules目录每次都是空的,因此必须在每次运行时下载/安装所有依赖项. 我们显然可以在 DinD 容器内从 Jenkins 挂载 an.m2 存储库,但是在此 DinD 容器内构建的图像将无法访问它。
我们尝试对 .m2 和tar
目录进行压缩,通过 Dockerfile 将它们COPY
到图像中, untar
并将它们move
到正确的路径,但此解决方法最多可保存 1-2 分钟。 我们还尝试使用buildkit
缓存 Maven 依赖项,例如https://www.baeldung.com/ops/docker-cache-maven-dependencies#caching-using-buildkit但这显然不是我们所需要的。
据我所知,不可能在docker build
上安装卷,这将是我们“空白缓存”情况下的理想解决方案。
有没有人遇到过类似的问题并找到了解决方法?
总的来说,我们将不胜感激任何关于如何最大限度地减少发布作业的执行时间并优化整个过程的建议。
先感谢您。
就像评论中提到的 SiHa 一样,您可以拥有一个内部包含预构建依赖项的图像。 这就是我可能会做的:
例如,使用轻量级node:16-alpine
图像(用于项目的angular
部分),从 github 克隆代码(使用depth=1
加速),运行npm install
并将图像推送到您的存储库。 在更新依赖项之前,您不必更改此映像。
在您的日常构建中,下载此映像并克隆 github 代码,然后仅运行npm run build
,因为node_modules
文件夹已在映像中。 使用FROM
将构建的代码复制到最终图像。
使用轻量级图像而不是克隆整个存储库应该会加快它的速度,并且使用具有预构建依赖项的图像可能比在图像中复制/提取依赖项更快 - 取决于硬件和网络速度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.