146 votes

Pourquoi l'installation de Pandas sur Alpine Linux prend-elle du temps ?

J'ai remarqué que l'installation de Pandas et Numpy (sa dépendance) dans un conteneur Docker en utilisant l'OS de base Alpine par rapport à CentOS ou Debian prend beaucoup plus de temps. J'ai créé un petit test ci-dessous pour démontrer la différence de temps. En dehors des quelques secondes que prend Alpine pour mettre à jour et télécharger les dépendances de construction pour installer Pandas et Numpy, pourquoi le setup.py prend-il environ 70x plus de temps que pour une installation Debian ?

Y a-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 vaut mieux utiliser pour des paquets comme Pandas et Numpy ?

Dockerfile.debian

FROM python:3.6.4-slim-jessie

RUN pip install pandas

Construire une image Debian avec Pandas et 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

Construire une image alpine avec Pandas et 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

2 votes

.apk maintenant disponible, donc plus besoin de construire à partir de la source - pkgs.alpinelinux.org/packages?name= *pandas&branches=bords

2 votes

@jtlz2, pandas n'est pas disponible sur la branche bordant Alpine. ce qui est dommage...

0 votes

@fccoelho Il est à nouveau disponible maintenant !

81voto

Nickolay Points 9297

Utilisation d'images basées sur Debian uniquement python pip pour installer les paquets avec .whl format :

  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 d'installation des logiciels Python plus rapide et plus fiable que la reconstruction du code source à chaque fois. Les fichiers WHL doivent seulement être déplacés à l'emplacement correct sur le système cible à installer, alors qu'une distribution source nécessite une étape de compilation avant l'installation.

Paquets 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 en utilisant python pip pendant le processus de construction, nous les compilons toujours à partir des fichiers sources dans alpine :

  Downloading pandas-0.22.0.tar.gz (11.3MB)
  Downloading numpy-1.14.1.zip (4.9MB)

et nous pouvons voir ce qui suit à l'intérieur du conteneur pendant la construction 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 Dockerfile un peu :

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 voulez utiliser l'image Alpine avec pandas dans CI par exemple, la meilleure façon de le faire est de le compiler une fois, de le pousser vers n'importe quel registre et de l'utiliser 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 docker. Il s'agit d'une image python avec des données pré-compilées. pandas sur la plateforme Alpine. Cela devrait vous faire gagner du temps.

4 votes

Eh bien, c'est dommage. Cependant, il semble que six, pytz et python-dateutil téléchargent des paquets .whl sur Alpine. Cela signifie-t-il qu'il est possible de construire des roues pour pandas et numpy pour Alpine, mais que ce n'est pas le cas actuellement ?

0 votes

Non, il n'est pas possible de construire des roues pour les produits suivants pandas y nampy sur la plate-forme alpine. Ces roues ne le supportent pas. Je l'ai montré dans la réponse, quand j'ai essayé d'installer les roues. pandas de son ensemble de roues en image alpine.

0 votes

@Nickolay Existe-t-il un moyen de contourner le recyclage d'un pandas construire que a ont été construits sur alpine et ensuite mis en cache ? (cela pourrait être hébergé quelque part localement)

38voto

user1021819 Points 372

RÉPONSE : EN DATE DU 25/10/2019, POUR PYTHON 3, CE N'EST TOUJOURS PAS LE CAS !

Voici un fichier Docker complet et fonctionnel :

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 construction est très sensible aux numéros de version exacts de python et d'alpine - se tromper semble provoquer l'erreur de Max Levy. so:libpython3.7m.so.1.0 (missing) - mais ce qui précède fonctionne maintenant pour moi.

Mon Dockerfile mis à jour est disponible à l'adresse suivante https://gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13b


[Mise à jour précédente :]

RÉPONSE : CE N'EST PAS LE CAS !

Dans tout Dockerfile Alpine, vous pouvez simplement faire*

RUN apk add py2-numpy@community py2-scipy@community py-pandas@edge

Cela s'explique par le fait que numpy , scipy et maintenant pandas sont toutes disponibles pré-intégrées 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&branches=bords

Une façon d'éviter de reconstruire à chaque fois, ou d'utiliser une couche Docker, est d'utiliser un système pré-construit, natif Alpine Linux/ .apk paquet, 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 où vous voulez dans votre Dockerfile :)

Cela vous évite également d'avoir à incorporer tout le reste dans l'image Docker avant le fait, c'est-à-dire la flexibilité de pré-construire n'importe quelle image Docker que vous voulez.

PS J'ai mis un stub de Dockerfile à https://gist.github.com/jtlz2/b0f4bc07ce2ff04bc193337f2327c13b qui montre grossièrement comment construire l'image. On y retrouve 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

2 votes

On dirait qu'il a été enlevé récemment ? pkgs.alpinelinux.org/package/edge/testing/x86/py-pandas

1 votes

@ChrisWedgwood Ils y travaillent activement - voir github.com/alpinelinux/aports/pull/6330

1 votes

@ChrisWedgwood Travailler à nouveau, ouf !

16voto

Un vrai conseil honnête ici, passez à une image basée sur Debian et tous vos problèmes disparaîtront.

Alpine pour les applications python ne fonctionne pas bien.

Voici un exemple de mon 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 est plus approprié dans ce cas, de plus, vous n'avez pas besoin de dépendance supplémentaire dans le système d'exploitation.

Suivez un article utile et récent : https://pythonspeed.com/articles/alpine-docker-python/ :

N'utilisez pas Alpine Linux pour les images Python À moins que vous ne vouliez des temps de construction massivement plus lents, des images plus grandes, plus de travail, et le potentiel pour des bogues obscurs, vous voudrez éviter Alpine Linux comme image de base. Pour quelques recommandations sur ce que vous devriez utiliser, voyez mon article sur le choix d'une bonne image de base.

9voto

stefanitsky Points 71

ATTENTION
Regardez la réponse de @jtlz2 avec la dernière mise à jour.

DERNIÈRE MISE À JOUR le 17/09/2019

Ainsi, les paquets py3-pandas et py3-numpy ont été déplacés vers le dépôt alpine de testing, vous pouvez donc les télécharger en ajoutant ces lignes dans votre Dockerfile :

RUN echo "http://dl-8.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \
  && apk update \
  && apk add py3-numpy py3-pandas

J'espère que cela aidera quelqu'un !

Liens vers les forfaits alpins :
- py3-pandas
- py3-numpy

Dépôts alpins info quais .

0 votes

Cela a marché pour moi ! Merci d'avoir fourni une réponse actualisée !

2 votes

Corrigé dans ma réponse

1 votes

@jtlz2 cool, merci, mais j'ai migré vers le buster debian au lieu d'alpine et je n'ai pas essayé de le réinstaller avec alpine, mais de toute façon, merci pour la réponse, j'ai également corrigé ma réponse.

9voto

ThisGuyCantEven Points 159

Je vais juste rassembler certaines de ces réponses dans une seule et même réponse et ajouter un détail qui, je pense, a été oublié. La raison pour laquelle certaines librairies python, en particulier les librairies mathématiques et de données optimisées, prennent autant de temps à construire sur Alpine est que les roues pip pour ces librairies incluent des binaires précompilés à partir de c/c++ et liés contre glibc un ensemble commun de bibliothèques standard c. Debian, Fedora, CentOS utilisent tous (généralement) glibc mais alpine, afin de rester léger, utilise musl-libc au lieu de cela. Les binaires c/c++ construits sur un glibc ne fonctionnera pas sur un système sans glibc et il en va de même pour musl .

Pip cherche d'abord une roue avec les binaires corrects, s'il n'en trouve pas, il essaie de compiler les binaires à partir des sources c/c++ et les lie à musl. Dans de nombreux cas, cela ne fonctionnera même pas à moins que vous ayez les en-têtes python de python3-dev ou des outils de construction comme make .

Le bon côté des choses, comme d'autres l'ont mentionné, c'est qu'il y a apk avec les binaires appropriés fournis par la communauté, leur utilisation vous évitera le processus (parfois long) de construction des binaires.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X