点10和apt:如何避免distutils包

时间:2018-04-20 01:58:13

标签: python docker pip distutils apt

我正在处理遗留的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选项,但是我再次遇到{{1}的同样问题论证揭示了另一件需要忽略的事情。

我可以将--ignore-installed固定在没有此限制的旧版本上,但我不想永远使用过时版本的pip

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

更新:

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

4 个答案:

答案 0 :(得分:49)

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

我所要做的就是添加

--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,但还没有得到令人满意的答案。但是,如果有任何负面影响,我们的生产环境尚未看到它们的影响,我认为风险很低/没有(至少这是我们的经验)。我能够确认在我们的情况下,当使用此标志时,未卸载现有安装,但始终使用较新的安装。

更新

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

答案 1 :(得分:1)

这对我有用-

pip install --ignore-installed

或sudo pip install --ignore-installed

或(在记事本内) 导入系统 !{sys.executable} -m pip install --ignore-installed

答案 2 :(得分: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

答案 3 :(得分:0)

对于Windows 写

conda update --all pip install --upgrade <Your package name>

OR

conda update --all pip install <Your package name>

OR

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

来自ERROR: Cannot uninstall 'wrapt'. during upgrade