一尘不染

pip 10和apt:如何避免distutils软件包出现“无法卸载X”错误

docker

我正在处理旧版Dockerfile。这是我正在处理的 非常简化的 版本:

FROM ubuntu:14.04

RUN apt-get -y update && apt-get -y install \
    python-pip \
    python-numpy # ...and many other packages

RUN pip install -U pip

RUN pip install -r /tmp/requirements1.txt # includes e.g., numpy==1.13.0
RUN pip install -r /tmp/requirements2.txt
RUN pip install -r /tmp/requirements3.txt

首先,使用安装多个软件包apt,然后使用安装多个软件包pippip版本10已发布,部分发布是此新限制:

删除了对卸载使用distutils安装的项目的支持。distutils安装的项目不包含指示该安装属于哪些文件的元数据,因此无法实际卸载它们,而仅删除表示已安装文件的元数据而将所有实际文件都留在后面是不可能的。

这在我的设置中导致以下问题。例如,首先apt安装python- numpy。稍后pip尝试从安装numpy例如的较新版本/tmp/requirements1.txt,并尝试卸载较旧的版本,但是由于新的限制,它无法删除此版本:

Installing collected packages: numpy
  Found existing installation: numpy 1.8.2
Cannot uninstall 'numpy'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

现在我知道目前有几种解决方案。

我无法python-numpy通过安装apt。但是,这会引起问题,因为需要python- numpy安装几个不同的软件包,并且我不知道系统的另一部分是否依赖于这些软件包。实际上,apt通过Dockerfile安装了几个软件包,而我删除的每个软件包似乎都揭示了另一个Cannot uninstall X错误,并删除了我们的应用程序可能依赖或可能不依赖的许多其他软件包。

--ignore-installed当我尝试pip安装已通过安装的东西时,我也可以使用该选项apt,但是同样,我对每个--ignore- installed参数都存在相同的问题,它揭示了另一个需要忽略的东西。

我可以pip使用没有此限制的较旧版本,但我不想pip永远使用过时的版本。

我一直在努力寻找一种好的解决方案,该解决方案只需对该旧Dockerfile进行最小的更改,并允许我们使用该文件部署的应用程序继续按原样运行。关于如何安全解决pip10个无法安装较新版本distutils软件包的问题的任何建议?谢谢!

更新:

我不知道--ignore- installed没有包就可以将其用作忽略所有已安装包的参数。我正在考虑这是否对我来说是一个不错的选择,并在这里对此进行了询问。


阅读 226

收藏
2020-06-17

共1个答案

一尘不染

这是我最终使用的解决方案,并且使用此修复程序后,我们的应用已在生产中运行了近一个月,没有任何问题:

我要做的就是添加

--ignore-installed

pip install我的dockerfile中出现错误的行。使用我原始问题中相同的dockerfile示例,固定的dockerfile如下所示:

FROM ubuntu:14.04

RUN apt-get -y update && apt-get -y install \
    python-pip \
    python-numpy # ...and many other packages

RUN pip install -U pip

RUN pip install -r /tmp/requirements1.txt --ignore-installed # don't try to uninstall existing packages, e.g., numpy
RUN pip install -r /tmp/requirements2.txt
RUN pip install -r /tmp/requirements3.txt

--ignore-installed我认为我找不到的文档不清楚(pip install --help只是说“忽略已安装的软件包(改为重新安装)。”),我在这里询问了此标志的潜在危险,但尚未获得令人满意的答案。但是,如果有任何负面影响,我们的生产环境尚未看到它们的影响,我认为风险很小/没有(至少这是我们的经验)。我可以确认在我们的情况下,使用此标志时,不会卸载现有安装,但始终使用较新的安装。

更新:

我想通过@ivan_pozdeev 突出此答案。他提供了该答案未包括的一些信息,并且还概述了我的解决方案的一些潜在副作用。

2020-06-17