Docker如何仅在发生更改时运行pip requirements.txt?

156
在 Dockerfile 中,我有一层用于安装 requirements.txt 的代码:
FROM python:2.7
RUN pip install -r requirements.txt

构建Docker镜像时,无论对此文件进行了何种更改,它都会运行整个进程而不受影响

我该如何确保当文件发生更改时,Docker只运行pip install -r requirements.txt

Removing intermediate container f98c845d0f05
Step 3 : RUN pip install -r requirements.txt
 ---> Running in 8ceb63abaef6
Collecting https://github.com/tomchristie/django-rest-framework/archive/master.zip (from -r requirements.txt (line 30))
  Downloading https://github.com/tomchristie/django-rest-framework/archive/master.zip
Collecting Django==1.8.7 (from -r requirements.txt (line 1))

1
请发布 docker build 的输出(和您的 Dockerfile)。 可能是构建过程中的早期步骤破坏了缓存,导致此步骤运行。 - Thomas Orozco
更新原帖,包含我目前拥有的所有内容。 - Prometheus
1
仅仅这一步是没有用的。请发布完整的输出(或至少是Dockerfile)。 - Thomas Orozco
3个回答

276

我假设在你的构建过程中的某个点上,你会使用 COPY 或者 ADD 命令将整个应用程序复制到 Docker 镜像中:

COPY . /opt/app
WORKDIR /opt/app
RUN pip install -r requirements.txt

问题是每次将整个应用程序复制到镜像中时,都会使Docker构建缓存无效。这也会使所有后续构建步骤的缓存无效。

为了解决这个问题,我建议在将整个应用程序添加到镜像之前,先将仅限于requirements.txt 文件复制到单独的构建步骤中:

COPY requirements.txt /opt/app/requirements.txt
WORKDIR /opt/app
RUN pip install -r requirements.txt
COPY . /opt/app
# continue as before...

由于要求文件本身很少发生更改,因此您可以在将应用程序代码添加到映像之前一直使用缓存的图层。


12
一般准则是,除非你需要ADD特定的功能,否则建议使用COPY - Metropolis
2
@Metropolis,你完全正确。谢谢你的提示。 - helmbert
6
同意@Metropolis的观点。只有当<src>文件夹包含需要解压缩的存档文件或需要支持远程URL处理时,才需要使用ADD{源代码} - Mohsin Aljiwala
由于需求文件本身可能很少更改,仅在开发过程中更改... :( - jtlz2

73
这在Docker自己的“编写Dockerfile的最佳实践”中直接提到了。

If you have multiple Dockerfile steps that use different files from your context, COPY them individually, rather than all at once. This will ensure that each step’s build cache is only invalidated (forcing the step to be re-run) if the specifically required files change.

For example:

COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
COPY . /tmp/

results in fewer cache invalidations for the RUN step, than if you put the COPY . /tmp/ before it.


-4

如果你不想每次安装库时都要输入 "yes" 确认,可以通过以下方式更快地运行 requirements.txt 文件:

COPY requirements.txt ./
RUN pip install -y -r requirements.txt
COPY ./"dir"/* .

1
这是什么的替代选择?而且我不记得在进行Docker构建时需要输入“yes”。很抱歉,我无法看出这个回答与问题的关系。 - Nikolay Hüttenberend

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接