我正在处理一个遗留的 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已经发布, 部分发布 就是这个新限制:
删除了对卸载已使用 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.
现在我知道在这一点上有几种解决方案。
我无法通过 apt
安装 python-numpy
。但是,这会导致问题,因为 python-numpy
安装了几个不同的包作为要求,我不知道系统的另一部分是否依赖这些包。实际上,通过 Dockerfile 安装了几个 apt
包,我删除的每个包似乎都揭示了另一个 Cannot uninstall X
错误,并随之删除了许多其他包,即我们的应用程序可能依赖也可能不依赖。
当我尝试 pip
安装已经通过 apt
安装的东西时,我也可以使用 --ignore-installed
选项,但是我又遇到了同样的问题 --ignore-installed
论证揭示了另一件需要忽略的事情。
我可以将 pip
在没有此限制的旧版本上,但我不想永远使用 pip
的过时版本。
我一直在兜圈子,试图提出一个好的解决方案,该解决方案涉及对这个遗留 Dockerfile 的最小更改,并允许我们使用该文件部署的应用程序继续像以前一样运行。关于如何安全地解决 pip
10 无法安装更新版本的 distutils
软件包的问题的任何建议?谢谢!
更新:
我没有意识到 --ignore-installed
可以在没有包的情况下用作忽略所有已安装包的参数。我正在考虑这对我来说是否是一个不错的选择,并 在这里 询问过。
原文由 elethan 发布,翻译遵循 CC BY-SA 4.0 许可协议
这是我最终采用的解决方案,并且我们的应用程序已经在生产环境中运行了近一个月,没有任何问题,并且修复了这个问题:
我所要做的就是添加
--ignore-installed
到我的 dockerfile 中引发错误的
pip install
行。使用我原始问题中的相同 dockerfile 示例,固定的 dockerfile 看起来像:在我看来,我可以找到的关于
--ignore-installed
的文档不清楚(pip install --help
只是说“忽略已安装的软件包(而是重新安装)。”),我询问了这方面的潜在危险 在这里 标记,但尚未得到满意的答案。但是,如果有任何负面影响,我们的生产环境还没有看到它们的影响,我认为风险很低/没有(至少这是我们的经验)。我能够确认在我们的例子中,当使用这个标志时,现有的安装并没有被卸载,但新的安装总是被使用。更新:
我想通过@ivan_pozdeev 强调 这个 答案。他提供了一些此答案未包含的信息,并且还概述了我的解决方案的一些潜在副作用。