在构建服务器上使用缓存构建 Docker 映像?

在构建服务器上使用缓存构建 Docker 映像?

我们有一个 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 构建更改的程度/频率。

相关内容