我最近开始使用多阶段 Docker 构建,看起来在中间构建过程中没有缓存。我不确定这是 Docker 的限制,还是某些功能不可用,或者我做错了什么。
我正在拉取最终构建,并在新构建开始时执行 --cache-from,但它总是运行完整的构建过程。
我最近开始使用多阶段 Docker 构建,看起来在中间构建过程中没有缓存。我不确定这是 Docker 的限制,还是某些功能不可用,或者我做错了什么。
我正在拉取最终构建,并在新构建开始时执行 --cache-from,但它总是运行完整的构建过程。
这似乎是docker本身的一个限制,在这个问题下有详细的描述 - https://github.com/moby/moby/issues/34715
解决方法是:
docker-compose
中使用它?我有一个已缓存的中间镜像,我使用docker load
加载,并在docker-compose.yml
中将cache_from
设置为同一镜像,但是它仍然会重新构建所有阶段。 - thisismydesign--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),然后您可以在YAML文件的build:
部分的args:
部分中设置BUILDKIT_INLINE_CACHE: 1
以确保设置所需的--build-arg
。我想在答案中再添加一个重要的观点
--build-arg BUILDKIT_INLINE_CACHE=1
仅缓存最后一层,并且仅在整个 Dockerfile 中没有更改的情况下才起作用。
因此,为了启用整个构建过程中层的缓存,应该将此参数替换为 --cache-to type=inline,mode=max
。请参阅文档
上述文档截至2023年3月28日如下:
生成缓存输出时,
--cache-to
参数接受一个mode
选项,用于定义要包含在导出缓存中的哪些层。除了inline
缓存之外,所有缓存后端都支持此选项。
这意味着,对于具有所有层的缓存中间状态,需要使用 registry
缓存后端。
我计划在构建时使用相同的image:tag
,但带有后缀-buildcache
。因此,--cache-from type=registry,ref=org/image:tag-buildcache,mode=max --cache-to type=registry,ref=org/image:tag-buildcache,mode=max
registry
缓存后端而不是inline
缓存后端来缓存所有层。从文档中可以看到:
--cache-from
不会帮助之前的阶段。保存之前的阶段可以起作用,但似乎只有在使用相同的计算机/文件系统构建时才能匹配层,因此实际上并不能帮助 CI 构建 :( - Aaron