J'ai remarqué que l'installation de Pandas et de Numpy (sa dépendance) dans un conteneur Docker utilisant le système d'exploitation de base Alpine vs. CentOS ou Debian prend beaucoup plus de temps. J'ai créé un petit test ci-dessous pour démontrer la différence de temps. Mis à part les quelques secondes nécessaires à Alpine pour mettre à jour et télécharger les dépendances de construction pour installer Pandas et Numpy, pourquoi setup.py prend-il environ 70 fois plus de temps que sous Debian?
Existe-t-il un moyen d'accélérer l'installation en utilisant Alpine comme image de base ou existe-t-il une autre image de base de taille comparable à Alpine, qu'il est préférable d'utiliser pour des packages tels que Pandas et Numpy?
Dockerfile.debian
FROM python:3.6.4-slim-jessie
RUN pip install pandas
Construire une image Debian avec Pandas & 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
Créer une image alpine avec Pandas & 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
Les images basées sur Debian utilisent uniquement python pip
pour installer les paquets au format .whl
:
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)
Le format WHL a été développé comme une méthode plus rapide et plus fiable pour installer le logiciel Python que de reconstruire chaque fois à partir du code source. Les fichiers WHL doivent uniquement être déplacés vers le bon emplacement sur le système cible à installer, tandis qu'une distribution source nécessite une étape de compilation avant l'installation.
Les ensembles de roues pandas
et numpy
ne sont pas pris en charge dans les images basées sur la plate-forme Alpine. C'est pourquoi, lorsque nous les installons à l'aide de python pip
pendant le processus de construction, nous les compilons toujours à partir des fichiers source d'Alpine:
Downloading pandas-0.22.0.tar.gz (11.3MB)
Downloading numpy-1.14.1.Zip (4.9MB)
et nous pouvons voir les éléments suivants dans le conteneur lors de la création de l'image:
/ # 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 nous modifions un peu Dockerfile
:
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
nous obtenons l'erreur suivante:
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
Malheureusement, le seul moyen d'installer pandas
sur une image alpine est d'attendre la fin de la construction.
Bien sûr, si vous souhaitez utiliser l'image Alpine avec pandas
dans CI, par exemple, la meilleure façon de le faire est de la compiler une fois. Transférez-la dans n'importe quel registre et utilisez-la comme image de base pour vos besoins.
EDIT: Si vous voulez utiliser l'image alpine avec pandas
, vous pouvez tirer mon nickgryg/Alpine-pandas image de docker. C'est une image python avec pandas
pré-compilée sur la plate-forme Alpine. Cela devrait vous faire gagner du temps.
[Mise à jour:]
RÉPONSE: CE N'EST PAS!
Dans n'importe quel fichier de docker alpin, vous pouvez simplement faire *
RUN apk add py2-numpy@community py2-scipy@community py-pandas@Edge
En effet, numpy
, scipy
et maintenant pandas
sont tous disponibles prédéfinis sur Alpine
:
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
Une façon d'éviter de reconstruire à chaque fois, ou d'utiliser une couche Docker, consiste à utiliser un paquetage natif Alpine Linux/.apk
pré-construit, par exemple .
https://github.com/sgerrand/Alpine-pkg-py-pandas
https://github.com/nbgallery/apks
Vous pouvez construire ces .apk
une fois et les utiliser n'importe où dans votre fichier Docker :)
Cela vous évite également de devoir tout incorporer dans l'image Docker avant le fait - c'est-à-dire la possibilité de pré-construire n'importe quelle image Docker de votre choix.
Post-scriptum J'ai mis un stub Dockerfile à https://Gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13b qui montre approximativement comment construire l'image. Celles-ci incluent les étapes 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