在 docker 构建中使用 pip 缓存目录

我希望尽快得到我的 pip install指令在我的 docker build内。

我读过 很多 职位,它解释了如果你的 requirements.txt没有改变,在应用程序的其余部分之前添加 requirements.txt会如何帮助你利用 Docker 自己的图像缓存。但是,当依赖关系确实发生变化时,这一点帮助都没有,哪怕只是轻微的变化。

下一步是我们是否可以使用一致的 pip 缓存目录。默认情况下,pip会在 ~/.cache/pip中缓存下载的软件包(在 Linux 上) ,所以如果你正在安装一个模块的相同版本,在系统的任何地方之前已经安装,它应该不需要再去下载它,而是简单地使用缓存版本。如果我们可以利用一个共享的缓存目录来进行 docker 构建,这将大大加快依赖性安装的速度。

但是,似乎没有任何简单的方法可以在运行 docker build时挂载卷。构建环境似乎基本上是不可穿透的。我发现 一篇文章提出了一种天才但复杂的方法,在主机上运行 rsync服务器,然后在构建中使用黑客技术获取主机 IP,从主机同步 pip 缓存。但是我不喜欢在 Jenkins 中运行 rsync 服务器的想法(即使在最好的情况下,这也不是最安全的平台)。

有人知道是否有其他方法可以更简单地实现共享缓存卷吗?

24593 次浏览

我建议你使用 Buildkit,也可以参考 这个

文件:

# syntax = docker/dockerfile:experimental
FROM python:3.6-alpine
RUN --mount=type=cache,target=/root/.cache/pip pip install pyyaml

注意 : abc0是必须的,你必须在 Dockerfile 的开头添加它来启用这个特性。

1.

第一个执行构建:

export DOCKER_BUILDKIT=1
docker build --progress=plain -t abc:1 . --no-cache

第一个日志:

#9 [stage-0 2/2] RUN --mount=type=cache,target=/root/.cache/pip pip install...
#9   digest: sha256:55b70da1cbbe4d424f8c50c0678a01e855510bbda9d26f1ac5b983808f3bf4a5
#9 name: "[stage-0 2/2] RUN --mount=type=cache,target=/root/.cache/pip pip install pyyaml"
#9  started: 2019-09-20 03:11:35.296107357 +0000 UTC
#9 1.955 Collecting pyyaml
#9 3.050   Downloading https://files.pythonhosted.org/packages/e3/e8/b3212641ee2718d556df0f23f78de8303f068fe29cdaa7a91018849582fe/PyYAML-5.1.2.tar.gz (265kB)
#9 5.006 Building wheels for collected packages: pyyaml
#9 5.007   Building wheel for pyyaml (setup.py): started
#9 5.249   Building wheel for pyyaml (setup.py): finished with status 'done'
#9 5.250   Created wheel for pyyaml: filename=PyYAML-5.1.2-cp36-cp36m-linux_x86_64.whl size=44104 sha256=867daf35eab43c2d047ad737ea1e9eaeb4168b87501cd4d62c533f671208acaa
#9 5.250   Stored in directory: /root/.cache/pip/wheels/d9/45/dd/65f0b38450c47cf7e5312883deb97d065e030c5cca0a365030
#9 5.267 Successfully built pyyaml
#9 5.274 Installing collected packages: pyyaml
#9 5.309 Successfully installed pyyaml-5.1.2
#9completed: 2019-09-20 03:11:42.221146294 +0000 UTC
#9 duration: 6.925038937s

从上面,您可以看到第一次,构建将下载 pyyaml 从互联网。

2.

第二个执行构建:

docker build --progress=plain -t abc:1 . --no-cache

第二根圆木:

#9 [stage-0 2/2] RUN --mount=type=cache,target=/root/.cache/pip pip install...
#9   digest: sha256:55b70da1cbbe4d424f8c50c0678a01e855510bbda9d26f1ac5b983808f3bf4a5
#9 name: "[stage-0 2/2] RUN --mount=type=cache,target=/root/.cache/pip pip install pyyaml"
#9  started: 2019-09-20 03:16:58.588157354 +0000 UTC
#9 1.786 Collecting pyyaml
#9 2.234 Installing collected packages: pyyaml
#9 2.270 Successfully installed pyyaml-5.1.2
#9completed: 2019-09-20 03:17:01.933398002 +0000 UTC
#9 duration: 3.345240648s

从上面,您可以看到构建不再从互联网下载包,只是使用缓存。注意,这不是传统的 Docker 构建缓存,因为我使用的是 --no-cache,它是我装入构建的 /root/.cache/pip

3.

第三个删除 buildkit 缓存的执行构建:

docker builder prune
docker build --progress=plain -t abc:1 . --no-cache

第三根圆木:

#9 [stage-0 2/2] RUN --mount=type=cache,target=/root/.cache/pip pip install...
#9   digest: sha256:55b70da1cbbe4d424f8c50c0678a01e855510bbda9d26f1ac5b983808f3bf4a5
#9 name: "[stage-0 2/2] RUN --mount=type=cache,target=/root/.cache/pip pip install pyyaml"
#9  started: 2019-09-20 03:19:07.434792944 +0000 UTC
#9 1.894 Collecting pyyaml
#9 2.740   Downloading https://files.pythonhosted.org/packages/e3/e8/b3212641ee2718d556df0f23f78de8303f068fe29cdaa7a91018849582fe/PyYAML-5.1.2.tar.gz (265kB)
#9 3.319 Building wheels for collected packages: pyyaml
#9 3.319   Building wheel for pyyaml (setup.py): started
#9 3.560   Building wheel for pyyaml (setup.py): finished with status 'done'
#9 3.560   Created wheel for pyyaml: filename=PyYAML-5.1.2-cp36-cp36m-linux_x86_64.whl size=44104 sha256=cea5bc4689e231df7915c2fc3abca225d4ee2e869a7540682aacb6d42eb17053
#9 3.560   Stored in directory: /root/.cache/pip/wheels/d9/45/dd/65f0b38450c47cf7e5312883deb97d065e030c5cca0a365030
#9 3.580 Successfully built pyyaml
#9 3.585 Installing collected packages: pyyaml
#9 3.622 Successfully installed pyyaml-5.1.2
#9completed: 2019-09-20 03:19:12.530742712 +0000 UTC
#9 duration: 5.095949768s

从上面,您可以看到如果删除 buildkit 缓存,软件包下载再次。

总之,它将在多次构建之间提供一个共享缓存,并且这个缓存只有在构建映像时才会挂载。但是,图像本身不会有这些缓存,所以避免了在图像中大量的中间层。

编辑那些正在使用 docker 的用户,并且懒得阅读评论... ... :

如果您设置了 COMPOSE _ DOCKER _ CLI _ BUILD = 1. 例如: COMPOSE _ DOCKER _ CLI _ BUILD = 1 DOCKER _ BUILDKIT = 1 DOCKER-compose build-

根据民间问题更新2020/09/02:

我不知道从哪个版本(我现在的版本是19.03.11) ,如果不为缓存目录指定 mode,缓存将不会在下次构建时重用。

不知道具体原因,但你可以在 Dockerfile 增加 mode=0755,,让它重新运作:

文件:

# syntax = docker/dockerfile:experimental
FROM python:3.6-alpine
RUN --mount=type=cache,mode=0755,target=/root/.cache/pip pip install pyyaml