首页 > 解决方案 > Docker 和 pip install:避免在已经安装了一些包的情况下安装所有包

问题描述

我正在使用 docker compose 来构建 Python 项目的堆栈。这是一个dockerfile处理需求的片段。

# Requirements are installed here to ensure they will be cached.
COPY ./requirements /requirements
RUN pip install --no-cache-dir -r /requirements/production.txt \
    && rm -rf /requirements

使用该配置,我可以缓存需求,但是当我修改production.txt(例如更新单个包)时,Docker 会重新安装所有内容。

我知道 Docker 需要创建一个新容器,但有没有办法避免重新安装所有东西,但只安装必要的东西?

标签: pythondockerpipdocker-compose

解决方案


在这种情况下,不,没有办法避免重新安装production.txt.

来自官方文档,在该Leverage build cache部分:

对于 ADD 和 COPY 指令,检查图像中文件的内容并为每个文件计算校验和。这些校验和中不考虑文件的最后修改时间和最后访问时间。在缓存查找期间,将校验和与现有图像中的校验和进行比较。如果文件中有任何更改,例如内容和元数据,则缓存无效

由于您已更改production.txt,因此缓存无效,docker 从先前有效的层开始并安装所有内容。

现在,如果您有多个requirements.txt文件,则可以通过执行单独的复制和安装步骤来利用一些缓存:

COPY requirements1.txt
RUN pip install --no-cache-dir -r requirements1.txt

COPY requirements2.txt
RUN pip install --no-cache-dir -r requirements2.txt

这可能有其他缺点,但它可能允许您通过将不太可能更新的长期存在的软件包requirements1.txt和不太稳定的软件包放入requirements2.txt. 然后更改requirements2.txt只会导致重新安装这些要求。

但是,作为警告,这也意味着更改将完全需要在步骤之后requirements1.txt重新安装。这与一个文件的原始行为没有什么不同,但要知道这里的顺序很重要。这种流程还有其他一些缺点,但它们变得相当迂腐。requirements2.txtrequirements1.txt


推荐阅读