是否可以缓存多阶段 docker 构建?

Posted

技术标签:

【中文标题】是否可以缓存多阶段 docker 构建?【英文标题】:Is it possible to cache multi-stage docker builds? 【发布时间】:2019-03-09 19:42:33 【问题描述】:

我最近切换到多阶段 docker 构建,中间构建似乎没有任何缓存。我不确定这是否是 docker 限制、一些不可用的东西或者我做错了什么。

我正在拉下最终构建并在新构建开始时执行 --cache-from,但它始终运行完整构建。

【问题讨论】:

请提供一些输出或日志。为什么你认为没有缓存? @NestorSokil 中间阶段的运行与任何会影响这些 docker 层的更改无关。 docs.docker.com/develop/develop-images/multistage-build/… 的“hello world”甚至做同样的事情。 早期阶段的层不在最终阶段,因此使用--cache-from 对早期阶段没有帮助。保存之前的阶段是可行的,但如果您继续使用相同的计算机/文件系统进行构建,它似乎只能工作并匹配层,因此实际上并不能帮助 CI 构建:( 【参考方案1】:

由于之前的答案已经发布,现在有一个使用 BuildKit 后端的解决方案:https://docs.docker.com/engine/reference/commandline/build/#specifying-external-cache-sources

这涉及将参数 --build-arg BUILDKIT_INLINE_CACHE=1 传递给您的 docker build 命令。您还需要通过设置环境变量DOCKER_BUILDKIT=1 来确保正在使用 BuildKit(在 Linux 上;我认为在使用最新版本的 Docker Desktop 时,BuildKit 可能是 Windows 上的默认后端)。完整的 CI 命令行解决方案可能类似于:

export DOCKER_BUILDKIT=1
# Use cache from remote repository, tag as latest, keep cache metadata
docker build -t yourname/yourapp:latest --cache-from yourname/yourapp:latest --build-arg BUILDKIT_INLINE_CACHE=1 .
# Push new build up to remote repository replacing latest
docker push yourname/yourapp:latest

其他一些评论者正在询问docker-compose。它也适用于此,尽管您需要另外指定环境变量 COMPOSE_DOCKER_CLI_BUILD=1 以确保 docker-compose 使用 docker CLI(感谢 DOCKER_BUILDKIT=1 使用 BuildKit),然后您可以在 args: 部分设置 BUILDKIT_INLINE_CACHE: 1 build: 部分的 YAML 文件,以确保设置了所需的 --build-arg

【讨论】:

【参考方案2】:

这似乎是 docker 本身的限制,并在此问题下进行了描述 - https://github.com/moby/moby/issues/34715

解决方法是:

    使用 --target 构建中间阶段 将中间图像推送到注册表 使用 --target 构建最终映像并使用多个 --cache-from 路径,列出所有中间映像和最终映像 将最终图像推送到注册表 对于后续构建,首先从注册表中拉取中间 + 最终图像

【讨论】:

它使用第一个匹配,因此首先列出最终图像,然后是中间图像。这在 CI 情况下不起作用,您从推送中拉到不同的机器,Docker --cache-from 处理中的一些错误。 github.com/moby/moby/issues/34715 您如何将它与docker-compose 一起使用?我有一个缓存的中间阶段图像,我 docker load 并将 cache_from 设置为 docker-compose.yml 中的同一图像,但无论如何它都会重建所有阶段。

以上是关于是否可以缓存多阶段 docker 构建?的主要内容,如果未能解决你的问题,请参考以下文章

Docker多阶段构建最佳实践

Docker自学笔记

# 谈谈 Docker 镜像多阶段构建

谈谈 Docker 镜像多阶段构建

使用 Docker 开发 - 使用多阶段构建镜像

如何让 Java 测试容器在 Docker 多阶段构建中工作?