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

问题描述 投票:23回答:3

我正在处理遗留的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安装几个软件包,然后使用pip安装几个软件包。 pip版本10已经发布,part of the release是这个新的限制:

删除了对卸载使用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会根据需要安装一些不同的软件包,而且我不知道系统的另一部分是否依赖于这些软件包。实际上,通过Dockerfile安装了几个apt软件包,我删除的每个软件包似乎都显示了另一个Cannot uninstall X错误,并删除了许多其他软件包,我们的应用程序可能依赖也可能不依赖。

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

我可以将pip固定在一个没有这个限制的旧版本上,但我不想被卡在永久使用过时版本的pip

我一直在试图提出一个很好的解决方案,包括对这个传统Dockerfile的最小改动,并允许我们使用该文件部署的应用程序继续运行。有关如何安全地解决pip 10无法安装较新版本的distutils包的问题的任何建议吗?谢谢!

UPDATE:

我没有意识到--ignore-installed可以在没有包的情况下用作忽略所有已安装包的参数。我正在考虑这对我来说是否是一个不错的选择,并且问过它here

python docker pip distutils apt
3个回答
77
投票

这是我最终使用的解决方案,并且我们的应用程序已经在生产中运行,并且在接下来的一个月内没有任何问题,并且此修复程序到位:

我所要做的就是添加

--ignore-installed

我的dockerfile中的pip install行引发了错误。使用我原始问题中的相同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只是说“忽略安装的软件包(重新安装)。”),我问这个标志here的潜在危险,但还没有得到令人满意的答案。但是,如果有任何负面影响,我们的生产环境尚未看到它们的影响,我认为风险很低/没有(至少这是我们的经验)。我能够确认在我们的情况下,当使用此标志时,未卸载现有安装,但始终使用较新的安装。

Update:

我想强调@ivan_pozdeev的this答案。他提供了一些这个答案不包括的信息,他还概述了我的解决方案的一些潜在副作用。


2
投票

这对我有用 -

pip install --ignore-installed <Your package name>

要么

sudo pip install --ignore-installed <Your package name>

或(在jupyter笔记本内)

import sys
!{sys.executable} -m pip install --ignore-installed <Your package name>

0
投票

您可以手动删除numpy,但保持apt安装其他依赖项。然后像以前一样使用pip来安装最新版本的numpy。

#Manually remove just numpy installed by distutils
RUN rm /usr/lib/python2.7/dist-packages/numpy-1.8.2.egg-info
RUN rm -r /usr/lib/python2.7/dist-packages/numpy

RUN pip install -U pip
RUN pip install -r /tmp/requirements1.txt

numpy的位置应该是相同的。但是,如果要确认位置,可以在不运行requirements.txt文件的情况下运行容器,并在容器内的python控制台中发出以下命令。

>>> import numpy
>>> print numpy.__file__
/usr/lib/python2.7/dist-packages/numpy/__init__.pyc
© www.soinside.com 2019 - 2024. All rights reserved.