python - txt - pip 10 y apt: cómo evitar los errores "No se puede desinstalar X" para los paquetes distutils
python 3.6 5 docker (3)
Estoy tratando con un legado Dockerfile. Aquí hay una versión muy simplificada de lo que estoy tratando:
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
Primero, se instalan varios paquetes con apt
, y luego se instalan varios paquetes con pip
. pip
versión 10 de pip
se ha lanzado, y parte de la versión es esta nueva restricción:
Se eliminó la compatibilidad para desinstalar proyectos que se han instalado utilizando distutils. Los proyectos instalados de distutils no incluyen metadatos que indiquen qué archivos pertenecen a esa instalación y, por lo tanto, es imposible desinstalarlos en lugar de solo eliminar los metadatos que dicen que se instalaron mientras se dejaron todos los archivos reales.
Esto lleva al siguiente problema en mi configuración. Por ejemplo, el primer apt
instala python-numpy
. Más tarde, pip
intenta instalar una versión más nueva de numpy
desde, por ejemplo, /tmp/requirements1.txt
, e intenta desinstalar la versión anterior, pero debido a la nueva restricción, no puede eliminar esta versión:
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.
Ahora sé que en este punto hay varias soluciones.
No pude instalar python-numpy
través de apt
. Sin embargo, esto causa problemas porque python-numpy
instala algunos paquetes diferentes como requisitos, y no sé si otra parte del sistema se basa en estos paquetes. Y, en realidad, hay varios paquetes apt
instalados a través del Dockerfile, y cada uno que elimino parece revelar otro error de Cannot uninstall X
y elimina una serie de otros paquetes junto con él, en los que nuestra aplicación puede confiar o no.
También podría usar la opción " --ignore-installed
cuando intento instalar las cosas que ya se instalaron a través de apt
, pero nuevamente tengo el mismo problema de cada argumento --ignore-installed
y revelando otra cosa que necesita ser ignorado
Podría marcar pip
en una versión anterior que no tiene esta restricción, pero no quiero quedarme atascado usando una versión obsoleta de pip
para siempre.
He estado dando vueltas en círculos tratando de encontrar una buena solución que implique cambios mínimos en este Dockerfile heredado, y permita que la aplicación que implementamos con ese archivo continúe funcionando como lo ha sido. ¿Alguna sugerencia sobre cómo puedo evitar con seguridad este problema de pip
10 no poder instalar versiones más recientes de paquetes de distutils
? ¡Gracias!
ACTUALIZAR:
No me di cuenta de que --ignore-installed
podría utilizarse sin un paquete como argumento para ignorar todos los paquetes instalados. Estoy considerando si esta podría o no ser una buena opción para mí, y he preguntado al respecto here .
Esta es la solución con la que terminé y nuestras aplicaciones se han estado ejecutando en producción sin ningún problema durante casi un mes con esta solución implementada:
Todo lo que tenía que hacer era agregar
--ignore-installed
a las líneas de pip install
en mi dockerfile que estaban generando errores. Usando el mismo ejemplo de dockerfile de mi pregunta original, el dockerfile fijo se vería así:
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
La documentación que pude encontrar para --ignore-installed
no estaba clara en mi opinión ( pip install --help
simplemente dice "Ignorar los paquetes instalados (reinstalarlos en su lugar)"), y pregunté sobre los posibles peligros de esta bandera here , pero todavía tienen que obtener una respuesta satisfactoria. Sin embargo, si hay efectos secundarios negativos, nuestro entorno de producción aún no ha visto los efectos de estos, y creo que el riesgo es bajo / ninguno (al menos esa ha sido nuestra experiencia). Pude confirmar que en nuestro caso, cuando se usó este indicador, la instalación existente no se desinstaló, pero siempre se usó la instalación más reciente.
Actualizar:
Quería destacar this respuesta por @ivan_pozdeev. Él proporciona cierta información que esta respuesta no incluye, y también describe algunos posibles efectos secundarios de mi solución.
Esto es lo que funcionó para mí--
pip instalar --mejor-instalado
o sudo pip install --ignore-instalado
o (dentro del cuaderno de juoyter) importar sys! {sys.executable} -m pip install --ignore-instalado
Simplemente puede eliminar numpy manualmente, pero mantenga las otras dependencias instaladas por apt. Luego use pip como antes para instalar la última versión de 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
La ubicación de numpy debería ser la misma. Pero si desea confirmar la ubicación, puede ejecutar el contenedor sin ejecutar los archivos Requirements.txt y emitir los siguientes comandos en la consola de Python dentro del contenedor.
>>> import numpy
>>> print numpy.__file__
/usr/lib/python2.7/dist-packages/numpy/__init__.pyc