![在构建服务器上使用缓存构建 Docker 映像?](https://linux22.com/image/673649/%E5%9C%A8%E6%9E%84%E5%BB%BA%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E4%BD%BF%E7%94%A8%E7%BC%93%E5%AD%98%E6%9E%84%E5%BB%BA%20Docker%20%E6%98%A0%E5%83%8F%EF%BC%9F.png)
我们有一个 Jenkins CI 服务器,它从 Git 获取我们的代码、构建它、创建 Docker 镜像,然后将其发送到一些生产服务器。
我们的项目主要是用 Python 编写的,因此“构建”涉及运行
pip install -r requirements.txt
运行起来还不错,只是有点慢。它必须通过网络获取包,还必须为其中一些包构建 C 库(而且“lxml”不小!)。
在开发中,我成功地使用了pip-accel
来加速这个过程。它有相同的接口,pip
但它缓存了 Python 下载和构建的 C 代码,所以
pip-accel install -r requirements.txt
很快。
我想为我们的生产版本执行此操作,但遇到了一些障碍。
显然,pip-accel
需要一个目录来存储缓存。由于我们的 CI 服务器运行构建,因此将其放在这个位置是合乎逻辑的。但是该pip install
命令在新的 Docker 容器内运行,因此它不能只访问该服务器上的公共目录。
Docker“卷”似乎是为与容器共享目录而设计的,但我们的构建发生在 内部(令人惊讶的是)docker build
,并且只docker run
允许您附加卷。您无法使用 附加卷docker build
。
我是不是漏掉了什么?如何docker build
在我所在的容器之外运行并与主机共享缓存文件夹?
答案1
我没有什么名声可以评论你的问题,所以我的回答也有一些问题。
我尝试创建与你相同的设置,但进行了最小化(基于你上面的解释),并且它似乎对 docker 自己的缓存机制有所改进
我的示例 Dockerfile 如下所示:
FROM ubuntu:14.04
RUN apt-get update \
&& apt-get install -y python-pip python-dev build-essential \
&& pip install pip-accel
COPY requirements.txt /requirements.txt
RUN pip-accel install -r /requirements.txt
CMD tail -f /dev/null
requirements.txt 如下所示:
Flask==0.8
Jinja2==2.6
Werkzeug==0.8.3
第一次构建后(查看更长时间),我添加了一个新库“chardet==1.0.1”,现在我的 requirements.txt 看起来像:
Flask==0.8
Jinja2==2.6
Werkzeug==0.8.3
chardet==1.0.1
运行 docker build 后,它确实使用了 docker 自己的所有缓存,其中也包含旧的 pip 库
anovil@anovil-Latitude-E6440:~/tmp/serverfault/docker$ time docker build --rm .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM ubuntu:14.04
---> 89d5d8e8bafb
...
...
Removing intermediate container 337c23340e7a
Step 5 : CMD tail -f /dev/null
---> Running in 5cb25bc75bbe
---> d3dfe184934b
Removing intermediate container 5cb25bc75bbe
Successfully built d3dfe184934b
real 0m6.325s
user 0m0.024s
sys 0m0.012s
因为,docker build 默认有 '--force-rm=false'、'--no-cache=false'。
如果您的 Jenkins CI 以不同的用户或不同的主机运行此构建,情况可能会有所不同。否则,这是一个在 Dockerfile 中排序命令的问题。
如果您还有疑问,您可以分享您的示例 Dockerfile,并在此告知您的 requirements.txt 每次 jenkins 构建更改的程度/频率。