Zabývám se dědičným souborem Dockerfile. Zde je velmi zjednodušená verze toho, co se zabývám:
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
Nejprve je několik balíčků instalováno pomocí apt
a několik balíčků je instalováno pomocí pip
. pip
verze 10 byla vydána a část tohoto vydání je toto nové omezení:
Byla odstraněna podpora pro odinstalaci projektů, které byly nainstalovány pomocí distutils. instalované projekty distutils neobsahují metadata označující, které soubory patří k této instalaci, a proto je nemůžete skutečně odinstalovat, nýbrž pouze odstranit metadata s tím, že byly nainstalovány, zatímco všechny skutečné soubory zůstaly v pozadí.
To vede k následujícímu problému v mém nastavení. Například první apt
nainstaluje python-numpy
. Později se pip
pokouší nainstalovat novější verzi numpy
z např. /tmp/requirements1.txt
a pokouší se odinstalovat starší verzi, ale kvůli novému omezení tuto verzi nemůže odstranit:
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.
Nyní vím, že v tomto bodě existuje několik řešení.
Nemohu nainstalovat python-numpy
prostřednictvím apt
. To však způsobuje problémy, protože python-numpy
nainstaluje několik různých balíčků jako požadavky a já nevím, zda se na tyto balíčky spoléhá jiná část systému. A ve skutečnosti existuje několik balíčků apt
instalovaných přes Dockerfile a každý z nich, který jsem odstranil, odhaluje další chybu Cannot uninstall X
a odstraňuje s sebou řadu dalších balíčků, na které se naše aplikace může nebo nemusí spoléhat.
Mohu také použít volbu --ignore-installed
, když se snažím pip
instalovat věci, které již byly nainstalovány prostřednictvím apt
, ale pak mám opět stejný problém s každým argumentem --ignore-installed
, který odhaluje další věc, kterou je třeba ignorovat.
Mohl bych připojit pip
na starší verzi, která toto omezení nemá, ale nechci být navždy zaseknuta pomocí zastaralé verze pip
.
Chodím v kruzích a snažím se přijít s dobrým řešením, které zahrnuje minimální změny tohoto dědičného souboru Dockerfile a umožňuje aplikaci, kterou tento soubor implementujeme, aby i nadále fungovala tak, jak byla. Jakékoli návrhy týkající se toho, jak mohu bezpečně obejít tento problém pip
10, protože nejsou schopny instalovat novější verze balíčků distutils
? Děkuji!
Neuvědomil jsem si, že --ignore-installed
by mohlo být použito bez balíčku jako argument pro ignorování všech nainstalovaných balíčků. Uvažuji o tom, zda to pro mě může být dobrá volba, a ptali jsme se na to zde .
Toto je řešení, s nímž jsem skončil, a naše aplikace fungují ve výrobě bez problémů po dobu téměř jednoho měsíce s touto opravou na místě:
Jediné, co jsem musel udělat, bylo přidat
--ignore-installed
do pip install
řádků v mém dockfile, které vykazovaly chyby. Použitím stejného příkladu dockerfile z mé původní otázky by pevný dockerfile vypadal jako:
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
Dokumentace, kterou jsem mohl najít pro --ignore-installed
, byla podle mého názoru nejasná (pip install --help
jednoduše říká: „Ignorujte nainstalované balíčky (místo toho přeinstalovat).“) A zeptal jsem se na potenciální nebezpečí tohoto příznaku zde , ale zatím jsem se nedostal uspokojující odpověď. Pokud však dojde k nějakým negativním vedlejším účinkům, naše výrobní prostředí ještě nevidí jejich důsledky a myslím si, že riziko je nízké/žádné (alespoň to byla naše zkušenost). Byl jsem schopen potvrdit, že v našem případě, když byl tento příznak použit, nebyla stávající instalace odinstalována, ale že byla vždy použita novější instalace.
Chtěl jsem zdůraznit toto odpověď od @ivan_pozdeev. Poskytuje některé informace, které tato odpověď nezahrnuje, a také nastiňuje některé potenciální vedlejší účinky mého řešení.
Numpy můžete odebrat pouze ručně, ale ostatní závislosti instalované aptem. Pak použijte pip jako před instalací nejnovější verze 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
Umístění numpy by mělo být stejné. Pokud však chcete potvrdit umístění, můžete spustit kontejner bez spuštění souborů requirements.txt a vydat následující příkazy v konzole python uvnitř kontejneru.
>>> import numpy
>>> print numpy.__file__
/usr/lib/python2.7/dist-packages/numpy/__init__.pyc
Tohle pro mě fungovalo -
pip install --ignore-installed
nebo Sudo pip install --ignore-installed
nebo (uvnitř poznámkového bloku) import sys ! {sys.executable} -m pip install --ignore-installed