我有两台带有docker的服务器和一台带有私有注册表的服务器。
我在第一台机器上构建了Dockerfile;然后我将图像推送到注册表。
是否可以使用我的注册表中的缓存立即在第二台机器上构建Dockerfile?如果不是,有没有办法加速构建“几乎”相同的Dockerfiles而不编写我自己的缓存?
它尝试设置--registry-mirror
,但没有帮助。
答案 0 :(得分:24)
注意:issue 20316 ("Pulling build cache")已关闭,因为PR 26839 ("Implement build cache based on history array")已合并。
它允许例如在--cache-from
中指定先前CI构建的图像。
添加指定在构建时用作缓存源的图像的功能。这些图像不需要具有本地父链,可以从其他注册表中提取。用户需要确保仅使用受信任的图像作为源。
用法:
docker pull myimage:v1.0
docker build --cache-from myimage:v1.0 -t myimage:v1.1 .
请参阅merge commit 7944480,了解docker 1.13 (January 2017)。
As commented的{p>javipolo
:
如果有人像我一样疯狂地重复使用图层,那么"技巧"是要传递给
--cache-from
正在重建的图像(并已将其拉出),也是用作FROM
中基础的图像。例:
Dockerfile
用于图片custom-gource:0.1
FROM base_image:2.2.1
RUN apt-get update && apt-get install gource
COPY myscript.sh /myscript.sh
为了在不再执行
apt-get
的情况下在其他主机中重建,您需要:
docker pull custom-gource:0.1
docker build --cache-from=base_image:2.2.1,custom-gource:0.1 . -t custom-gource:0.2
这看起来似乎太明显了,但我一直在努力解决这个问题,直到我知道你需要包括基本图像
答案 1 :(得分:10)
for docker> 1.10,我在这个问题上找到了一些东西:https://github.com/docker/docker/issues/20316#issuecomment-221289631
鉴于此Dockerfile
FROM busybox
RUN mkdir this-is-a-test
RUN echo "hello world"
运行docker build -t caching-test .
然后我们可以看到包含docker history caching-test
3e4a484f0e67 About an hour ago /bin/sh -c echo "Hello world!" 0 B
6258cdec0c4b About an hour ago /bin/sh -c mkdir this-is-a-test 0 B
47bcc53f74dc 9 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0 B
<missing> 9 weeks ago /bin/sh -c #(nop) ADD file:47ca6e777c36a4cfff 1.113 MB
1.11中保存/加载的更改保留了父层和子层之间的关系,但只有当它们通过docker save保存在一起时才会保留。我们可以通过运行docker inspect test | grep Parent.
$ docker inspect caching-test | grep Parent
"Parent": "sha256:6258cdec0c4bef5e5627f301b541555883e6c4b385d0798a7763cb191168ce09",
这是Docker历史输出中的第二个顶层。
要使用保存和加载重新创建缓存,您需要保存所有作为父项引用的图像和图层。实际上,这通常意味着您需要在同一命令中保存每个图层以及FROM图像。
docker save caching-test 6258cdec0c4b busybox > caching-test.tar
- 请注意,我们还可以为保存命令提供图层名称而不是ID。
让我们清除所有内容,然后从tar文件重新加载图像。
docker rmi $(docker images -q)
。确认没有图像。
然后运行docker load -i caching-test.tar
。如果你看图像,你会看到busybox,然后是缓存测试。运行docker history caching-test
将显示与最初构建映像时完全相同的输出。这是因为通过保存和加载保留了父/子关系。您甚至可以运行docker inspect caching-test | grep Parent
并查看与父图层完全相同的ID。
运行相同Dockerfile的重建将向您显示正在使用缓存。
Sending build context to Docker daemon 5.391 MB
Step 1 : FROM busybox
---> 47bcc53f74dc
Step 2 : RUN mkdir this-is-a-test
---> Using cache
---> 6258cdec0c4b
Step 3 : RUN echo "hello world"
---> Using cache
---> 3e4a484f0e67
Successfully built 3e4a484f0e67
编辑:下面只有在docker 1.10之前
在第二台机器上,您可以在构建新机器之前docker pull theimagefromthefirstdockerfileontheregistry
。
这样你可以确定第二台机器上都存在每一层。
每次构建一个图层时,docker-engine都不会查询注册表(它甚至不知道它),它会太慢/太重,所以我不认为还有另一种方法。
答案 2 :(得分:7)
对于Docker版本> = 19.03,可以使用新的BuildKit功能来避免在构建之前必须提取远程映像。通过设置DOCKER_BUILDKIT环境变量来激活BuildKit,然后使用BUILDKIT_INLINE_CACHE build参数打开内联缓存以将构建缓存以及映像存储在注册表中,如下所示:
export DOCKER_BUILDKIT=1
docker build -t registry/imagename:tag --cache-from registry/imagename:tag --build-arg BUILDKIT_INLINE_CACHE=1 .
docker push registry/imagename:tag
感谢Nicholas Dille的解决方案。