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

Tim*_*Tim 7 deployment python build-server pip docker

我们有一个 Jenkins CI 服务器,它从 Git 获取我们的代码,构建它,制作一个 Docker 镜像,然后将它发送到一些生产服务器。

我们的项目主要是用 Python 编写的,所以“构建”涉及运行

pip install -r requirements.txt
Run Code Online (Sandbox Code Playgroud)

效果很好,只是有点慢。它必须通过网络获取包,另外还必须为其中一些构建 C 库(而且“lxml”并不小!)。

在开发中,我已经成功地pip-accel用来加速这个过程。它具有相同的接口,pip但它同时缓存 Python 下载和构建的 C 代码,所以

pip-accel install -r requirements.txt
Run Code Online (Sandbox Code Playgroud)

很快。

我想为我们的生产版本这样做,但我遇到了一些障碍。

显然,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
Run Code Online (Sandbox Code Playgroud)

需求.txt 如下所示:

Flask==0.8
Jinja2==2.6
Werkzeug==0.8.3
Run Code Online (Sandbox Code Playgroud)

第一次构建这个库后(看起来更长的时间),我添加了一个新库“chardet==1.0.1”,现在我的requirements.txt看起来像:

Flask==0.8
Jinja2==2.6
Werkzeug==0.8.3
chardet==1.0.1
Run Code Online (Sandbox Code Playgroud)

运行 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
Run Code Online (Sandbox Code Playgroud)

因为,docker build默认有'--force-rm=false','--no-cache=false'。
如果您的 Jenkins CI 作为不同用户或在不同主机中运行此构建,情况可能会有所不同。否则,就需要对 Dockerfile 中的命令进行排序。
如果您仍然有疑问,您能否分享您的示例 Dockerfile,并在此告知您的requirements.txt 对每个 jenkins 构建的更改程度/频率。