レガシー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
は、たとえば/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 。
これは私が最終的に解決したソリューションであり、私たちのアプリはこの修正を適用してほぼ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による回答。彼は、この答えに含まれていない情報を提供し、私のソリューションの潜在的な副作用についても概説しています。
これは私のために働いたものです-
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>
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