web-dev-qa-db-ja.com

pip 10およびapt:distutilsパッケージの「Xをアンインストールできません」エラーを回避する方法

レガシー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のインストール済みプロジェクトには、そのインストールに属するファイルを示すメタデータが含まれていないため、実際のファイルをすべて残してインストールされたというメタデータを削除するのではなく、実際にアンインストールすることはできません。

これにより、セットアップで次の問題が発生します。たとえば、最初のaptpython-numpyをインストールします。後でpipは、たとえば/tmp/requirements1.txtなどからnumpyの新しいバージョンをインストールしようとし、古いバージョンをアンインストールしようとしますが、新しい制限のため、このバージョンを削除できません。

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エラーを明らかにしているように見えます。依存しないかもしれません。

pipを介して既にインストールされているものをaptをインストールしようとするときに--ignore-installedオプションを使用することもできますが、すべての--ignore-installed引数に同じ問題があります無視する必要があるさらに別のことを明らかにする。

この制限のない古いバージョンにpipを固定することはできますが、pipの古いバージョンを永久に使用することはできません。

私は、このレガシーDockerfileに最小限の変更を加え、そのファイルでデプロイするアプリが以前のように機能し続けることを可能にする優れたソリューションを考え出そうと試みてきました。 pip 10の新しいバージョンのdistutilsパッケージをインストールできないという問題を安全に回避する方法に関する提案はありますか?ありがとうございました!

更新:

--ignore-installedが、インストールされているすべてのパッケージを無視する引数としてパッケージなしで使用できることを知りませんでした。これが私にとって良い選択肢であるかどうかを検討しており、それについて尋ねました here

35
elethan

これは私が最終的に解決したソリューションであり、私たちのアプリはこの修正を適用してほぼ1か月間、問題なく本番環境で実行されています。

私がしなければならなかったのは、追加することでした

--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は単に「インストールされたパッケージを無視します(代わりに再インストール)」と言います)、このフラグの潜在的な危険性について尋ねました こちら 、しかしまだ満足のいく答えを得ていない。ただし、マイナスの副作用がある場合、私たちの実稼働環境ではそれらの影響がまだ確認されておらず、リスクは低い/ゼロだと思います(少なくともそれは私たちの経験です)。このフラグを使用した場合、既存のインストールはアンインストールされず、新しいインストールが常に使用されたことを確認できました。

更新:

ハイライトしたい this @ivan_pozdeevによる回答。彼は、この答えに含まれていない情報を提供し、私のソリューションの潜在的な副作用についても概説しています。

76
elethan

これは私のために働いたものです-

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>
2
Archie Jain

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
0
Moharnab Saikia