Me di cuenta de que instalar Pandas y Numpy (su dependencia) en un contenedor Docker usando el sistema operativo base Alpine vs. CentOS o Debian lleva mucho más tiempo. Creé una pequeña prueba a continuación para demostrar la diferencia horaria. Aparte de los pocos segundos que Alpine tarda en actualizar y descargar las dependencias de compilación para instalar Pandas y Numpy, ¿por qué setup.py tarda unas 70 veces más que en la instalación de Debian?
¿Hay alguna forma de acelerar la instalación usando Alpine como imagen base o hay otra imagen base de tamaño comparable a Alpine que sea mejor para usar con paquetes como Pandas y Numpy?
Dockerfile.debian
FROM python:3.6.4-slim-jessie
RUN pip install pandas
Cree una imagen de Debian con Pandas y Numpy:
[PandasDockerTest] time docker build -t debian-pandas -f Dockerfile.debian . --no-cache
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM python:3.6.4-slim-jessie
---> 43431c5410f3
Step 2/2 : RUN pip install pandas
---> Running in 2e4c030f8051
Collecting pandas
Downloading pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl (26.2MB)
Collecting numpy>=1.9.0 (from pandas)
Downloading numpy-1.14.1-cp36-cp36m-manylinux1_x86_64.whl (12.2MB)
Collecting pytz>=2011k (from pandas)
Downloading pytz-2018.3-py2.py3-none-any.whl (509kB)
Collecting python-dateutil>=2 (from pandas)
Downloading python_dateutil-2.6.1-py2.py3-none-any.whl (194kB)
Collecting six>=1.5 (from python-dateutil>=2->pandas)
Downloading six-1.11.0-py2.py3-none-any.whl
Installing collected packages: numpy, pytz, six, python-dateutil, pandas
Successfully installed numpy-1.14.1 pandas-0.22.0 python-dateutil-2.6.1 pytz-2018.3 six-1.11.0
Removing intermediate container 2e4c030f8051
---> a71e1c314897
Successfully built a71e1c314897
Successfully tagged debian-pandas:latest
docker build -t debian-pandas -f Dockerfile.debian . --no-cache 0.07s user 0.06s system 0% cpu 13.605 total
Dockerfile.alpine
FROM python:3.6.4-alpine3.7
RUN apk --update add --no-cache g++
RUN pip install pandas
Crea una imagen alpina con Pandas y Numpy:
[PandasDockerTest] time docker build -t alpine-pandas -f Dockerfile.alpine . --no-cache
Sending build context to Docker daemon 16.9kB
Step 1/3 : FROM python:3.6.4-alpine3.7
---> 4b00a94b6f26
Step 2/3 : RUN apk --update add --no-cache g++
---> Running in 4b0c32551e3f
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/17) Upgrading musl (1.1.18-r2 -> 1.1.18-r3)
(2/17) Installing libgcc (6.4.0-r5)
(3/17) Installing libstdc++ (6.4.0-r5)
(4/17) Installing binutils-libs (2.28-r3)
(5/17) Installing binutils (2.28-r3)
(6/17) Installing gmp (6.1.2-r1)
(7/17) Installing isl (0.18-r0)
(8/17) Installing libgomp (6.4.0-r5)
(9/17) Installing libatomic (6.4.0-r5)
(10/17) Installing pkgconf (1.3.10-r0)
(11/17) Installing mpfr3 (3.1.5-r1)
(12/17) Installing mpc1 (1.0.3-r1)
(13/17) Installing gcc (6.4.0-r5)
(14/17) Installing musl-dev (1.1.18-r3)
(15/17) Installing libc-dev (0.7.1-r0)
(16/17) Installing g++ (6.4.0-r5)
(17/17) Upgrading musl-utils (1.1.18-r2 -> 1.1.18-r3)
Executing busybox-1.27.2-r7.trigger
OK: 184 MiB in 50 packages
Removing intermediate container 4b0c32551e3f
---> be26c3bf4e42
Step 3/3 : RUN pip install pandas
---> Running in 36f6024e5e2d
Collecting pandas
Downloading pandas-0.22.0.tar.gz (11.3MB)
Collecting python-dateutil>=2 (from pandas)
Downloading python_dateutil-2.6.1-py2.py3-none-any.whl (194kB)
Collecting pytz>=2011k (from pandas)
Downloading pytz-2018.3-py2.py3-none-any.whl (509kB)
Collecting numpy>=1.9.0 (from pandas)
Downloading numpy-1.14.1.zip (4.9MB)
Collecting six>=1.5 (from python-dateutil>=2->pandas)
Downloading six-1.11.0-py2.py3-none-any.whl
Building wheels for collected packages: pandas, numpy
Running setup.py bdist_wheel for pandas: started
Running setup.py bdist_wheel for pandas: still running...
Running setup.py bdist_wheel for pandas: still running...
Running setup.py bdist_wheel for pandas: still running...
Running setup.py bdist_wheel for pandas: still running...
Running setup.py bdist_wheel for pandas: still running...
Running setup.py bdist_wheel for pandas: still running...
Running setup.py bdist_wheel for pandas: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/e8/ed/46/0596b51014f3cc49259e52dff9824e1c6fe352048a2656fc92
Running setup.py bdist_wheel for numpy: started
Running setup.py bdist_wheel for numpy: still running...
Running setup.py bdist_wheel for numpy: still running...
Running setup.py bdist_wheel for numpy: still running...
Running setup.py bdist_wheel for numpy: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/9d/cd/e1/4d418b16ea662e512349ef193ed9d9ff473af715110798c984
Successfully built pandas numpy
Installing collected packages: six, python-dateutil, pytz, numpy, pandas
Successfully installed numpy-1.14.1 pandas-0.22.0 python-dateutil-2.6.1 pytz-2018.3 six-1.11.0
Removing intermediate container 36f6024e5e2d
---> a93c59e6a106
Successfully built a93c59e6a106
Successfully tagged alpine-pandas:latest
docker build -t alpine-pandas -f Dockerfile.alpine . --no-cache 0.54s user 0.33s system 0% cpu 16:08.47 total
Respuestas:
Las imágenes basadas en Debian se usan solo
python pip
para instalar paquetes con.whl
formato:Downloading pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl (26.2MB) Downloading numpy-1.14.1-cp36-cp36m-manylinux1_x86_64.whl (12.2MB)
El formato WHL se desarrolló como un método más rápido y confiable de instalar software Python que la reconstrucción desde el código fuente cada vez. Los archivos WHL solo deben moverse a la ubicación correcta en el sistema de destino para ser instalados, mientras que una distribución de origen requiere un paso de compilación antes de la instalación.
Los paquetes de ruedas
pandas
ynumpy
no son compatibles con imágenes basadas en la plataforma Alpine. Es por eso que cuando los instalamos usandopython pip
durante el proceso de construcción, siempre los compilamos a partir de los archivos fuente en alpine:Downloading pandas-0.22.0.tar.gz (11.3MB) Downloading numpy-1.14.1.zip (4.9MB)
y podemos ver el siguiente contenedor interior durante la construcción de la imagen:
/ # ps aux PID USER TIME COMMAND 1 root 0:00 /bin/sh -c pip install pandas 7 root 0:04 {pip} /usr/local/bin/python /usr/local/bin/pip install pandas 21 root 0:07 /usr/local/bin/python -c import setuptools, tokenize;__file__='/tmp/pip-build-en29h0ak/pandas/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n 496 root 0:00 sh 660 root 0:00 /bin/sh -c gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -DTHREAD_STACK_SIZE=0x100000 -fPIC -Ibuild/src.linux-x86_64-3.6/numpy/core/src/pri 661 root 0:00 gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -DTHREAD_STACK_SIZE=0x100000 -fPIC -Ibuild/src.linux-x86_64-3.6/numpy/core/src/private -Inump 662 root 0:00 /usr/libexec/gcc/x86_64-alpine-linux-musl/6.4.0/cc1 -quiet -I build/src.linux-x86_64-3.6/numpy/core/src/private -I numpy/core/include -I build/src.linux-x86_64-3.6/numpy/core/includ 663 root 0:00 ps aux
Si modificamos
Dockerfile
un poco:FROM python:3.6.4-alpine3.7 RUN apk add --no-cache g++ wget RUN wget https://pypi.python.org/packages/da/c6/0936bc5814b429fddb5d6252566fe73a3e40372e6ceaf87de3dec1326f28/pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl RUN pip install pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl
obtenemos el siguiente error:
Step 4/4 : RUN pip install pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl ---> Running in 0faea63e2bda pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl is not a supported wheel on this platform. The command '/bin/sh -c pip install pandas-0.22.0-cp36-cp36m-manylinux1_x86_64.whl' returned a non-zero code: 1
Desafortunadamente, la única forma de instalar
pandas
una imagen de Alpine es esperar hasta que finalice la compilación.Por supuesto, si desea usar la imagen de Alpine con
pandas
CI, por ejemplo, la mejor manera de hacerlo es compilarla una vez, enviarla a cualquier registro y usarla como imagen base para sus necesidades.EDITAR: Si desea usar la imagen de Alpine con
pandas
, puede extraer mi imagen de la ventana acoplable nickgryg / alpine-pandas . Es una imagen de Python precompiladapandas
en la plataforma Alpine. Debería ahorrarle tiempo.fuente
pandas
ynampy
sobre plataforma alpina. Esas ruedas no lo soportan. Mostré eso en la respuesta, cuando intenté instalarpandas
desde su paquete de ruedas en una imagen alpina.pandas
compilación que se ha construidoalpine
y luego almacenada en caché? (esto podría estar alojado en algún lugar localmente)RESPUESTA: A PARTIR DEL 9/03/2020, ¡PARA PYTHON 3, TODAVÍA NO ES!
Aquí hay un Dockerfile completo en funcionamiento:
FROM python:3.7-alpine RUN echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories RUN apk add --update --no-cache py3-numpy py3-pandas@testing
La compilación es muy sensible a los números exactos de la versión de Python y Alpine; hacerlos mal parece provocar el error de Max Levy,
so:libpython3.7m.so.1.0 (missing)
pero lo anterior ahora funciona para mí.Mi Dockerfile actualizado está disponible en https://gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13b
[Actualización anterior:]
RESPUESTA: ¡NO ES!
En cualquier Alpine Dockerfile puede simplemente hacer *
Esto se debe a que
numpy
,scipy
y ahorapandas
todos están disponibles precompilados enalpine
:https://pkgs.alpinelinux.org/packages?name=*numpy
https://pkgs.alpinelinux.org/packages?name=*scipy&branch=edge
https://pkgs.alpinelinux.org/packages?name=*pandas&branch=edge
Una forma de evitar la reconstrucción cada vez, o el uso de una capa de Docker, es usar un
.apk
paquete / Alpine Linux nativo precompilado , por ejemplohttps://github.com/sgerrand/alpine-pkg-py-pandas
https://github.com/nbgallery/apks
Puede compilar estos
.apk
s una vez y usarlos en cualquier lugar de su Dockerfile que desee :)Esto también le ahorra tener que hornear todo lo demás en la imagen de Docker antes del hecho, es decir, la flexibilidad para preconstruir cualquier imagen de Docker que desee.
PD: he puesto un código auxiliar de Dockerfile en https://gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13b que muestra aproximadamente cómo construir la imagen. Estos incluyen los pasos importantes (*):
RUN echo "@community http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories RUN apk update RUN apk add --update --no-cache libgfortran
fuente
ATENCIÓN
Mira la respuesta de @ jtlz2 con la última actualización
ANTICUADO
Entonces, los paquetes py3-pandas y py3-numpy se movieron al repositorio de prueba alpine, por lo que puede descargarlo agregando estas líneas a su Dockerfile:
RUN echo "http://dl-8.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \ && apk update \ && apk add py3-numpy py3-pandas
fuente
Solo voy a reunir algunas de estas respuestas en una sola respuesta y agregar un detalle que creo que se perdió. La razón por la que ciertas bibliotecas de Python, particularmente las bibliotecas de datos y matemáticas optimizadas, tardan tanto en construirse en alpine es porque las ruedas pip de estas bibliotecas incluyen binarios precompilados de c / c ++ y vinculados a
glibc
un conjunto común de bibliotecas estándar de c. Debian, Fedora, CentOS todos (normalmente) usanglibc
, pero alpine, para mantenerse livianos, usa en sumusl-libc
lugar. Los binarios de c / c ++ construidos en unglibc
sistema no funcionarán en un sistema sin ellosglibc
y lo mismo ocurremusl
.Pip busca primero una rueda con los binarios correctos, si no puede encontrar uno, intenta compilar los binarios de la fuente c / c ++ y los vincula con musl. En muchos casos, esto ni siquiera funcionará a menos que tenga los encabezados de Python
python3-dev
o compile herramientas comomake
.Ahora, el lado positivo, como otros han mencionado, hay
apk
paquetes con los binarios adecuados proporcionados por la comunidad, usarlos le ahorrará el (a veces largo) proceso de construcción de los binarios.fuente
Un consejo realmente honesto aquí, cambie a una imagen basada en Debian y luego todos sus problemas desaparecerán.
Alpine para aplicaciones de Python no funciona bien.
Aquí hay un ejemplo de mi
dockerfile
:FROM python:3.7.6-buster RUN pip install pandas==1.0.0 RUN pip install sklearn RUN pip install Django==3.0.2 RUN pip install cx_Oracle==7.3.0 RUN pip install excel RUN pip install djangorestframework==3.11.0
El
python:3.7.6-buster
es más apropiado en este caso, además, no se necesita ninguna dependencia adicional en el sistema operativo.Siga un artículo útil y reciente: https://pythonspeed.com/articles/alpine-docker-python/ :
fuente
pip --no-cache
para reducir un poco más la huella. Lo que realmente debería hacer es ponerlos línea por línea en unrequirements.txt
archivo ypip install --no-cache -r requirements.txt
Esto funcionó para mí:
FROM python:3.8-alpine RUN echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories RUN apk add --update --no-cache py3-numpy py3-pandas@testing ENV PYTHONPATH=/usr/lib/python3.8/site-packages COPY . /app WORKDIR /app RUN pip install -r requirements.txt EXPOSE 5003 ENTRYPOINT [ "python" ] CMD [ "app.py" ]
La mayor parte del código aquí es de la respuesta de jtlz2 de este mismo hilo y Faylixe de otro hilo.
Resulta que la versión más ligera de pandas se encuentra en el repositorio de Alpine,
py3-numpy
pero no se instala en la misma ruta de archivo desde donde Python lee las importaciones de forma predeterminada. Por lo tanto, debe agregar elENV
. También tenga en cuenta la versión alpina.fuente
pandas
se considera un paquete respaldado por la comunidad, por lo que las respuestas que apuntanedge/testing
no funcionarán ya que Alpine no admite oficialmente pandas como paquete principal (todavía funciona, simplemente no es compatible con los desarrolladores principales de Alpine).Prueba este Dockerfile:
FROM python:3.8-alpine RUN echo "@community http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories \ && apk add py3-pandas@community
Esto también funciona para la imagen vainilla de Alpine, usando
FROM alpine:3.12
.fuente
alpine lleva mucho tiempo instalar pandas y el tamaño de la imagen también es enorme. Probé la versión python: 3.8-slim-buster de la imagen base de Python. La creación de la imagen fue muy rápida y el tamaño de la imagen fue inferior a la mitad en comparación con la imagen del acoplador de pitón alpino
https://github.com/dguyhasnoname/k8s-cluster-checker/blob/master/Dockerfile
fuente