
Alpine Linux est souvent recommandé comme image de base pour Docker. On vous dit que l'utilisation d'Alpine rendra vos builds plus petits et le processus de construction plus rapide.
Mais si vous utilisez Alpine Linux pour des applications Python, alors il :
- Ralentit considérablement vos builds
- Augmente la taille de vos images
- Fait perdre votre temps
- Et peut finalement causer des erreurs à l'exécution
Examinons pourquoi Alpine est recommandé, mais pourquoi vous ne devriez pas l'utiliser avec Python.
Pourquoi les gens recommandent-ils Alpine ?
Supposons que nous ayons besoin de gcc comme partie de notre image et que nous souhaitions comparer Alpine Linux Ă Ubuntu 18.04, en termes de vitesse de construction et de taille finale de l'image.
Pour commencer, téléchargeons deux images et comparons leur taille :
$ docker pull --quiet ubuntu:18.04
docker.io/library/ubuntu:18.04
$ docker pull --quiet alpine
docker.io/library/alpine:latest
$ docker image ls ubuntu:18.04
REPOSITORY TAG IMAGE ID SIZE
ubuntu 18.04 ccc6e87d482b 64.2MB
$ docker image ls alpine
REPOSITORY TAG IMAGE ID SIZE
alpine latest e7d92cdc71fe 5.59MB
Comme vous pouvez le voir, l'image de base pour Alpine est beaucoup plus petite. Essayons maintenant d'installer gcc en commençant par Ubuntu :
FROM ubuntu:18.04
RUN apt-get update &&
apt-get install --no-install-recommends -y gcc &&
apt-get clean && rm -rf /var/lib/apt/lists/*
Ăcrire un Dockerfile parfait dĂ©passe le cadre de cet article.
Mesurons la vitesse de construction :
$ time docker build -t ubuntu-gcc -f Dockerfile.ubuntu --quiet .
sha256:b6a3ee33acb83148cd273b0098f4c7eed01a82f47eeb8f5bec775c26d4fe4aae
réel 0m29.251s
utilisateur 0m0.032s
systĂšme 0m0.026s
$ docker image ls ubuntu-gcc
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu-gcc latest b6a3ee33acb8 9 secondes ago 150MB
RĂ©pĂ©tons la mĂȘme chose pour Alpine (Dockerfile) :
FROM alpine
RUN apk add --update gcc
Construisons, regardons le temps et la taille de la construction :
$ time docker build -t alpine-gcc -f Dockerfile.alpine --quiet .
sha256:efd626923c1478ccde67db28911ef90799710e5b8125cf4ebb2b2ca200ae1ac3
réel 0m15.461s
utilisateur 0m0.026s
systĂšme 0m0.024s
$ docker image ls alpine-gcc
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine-gcc latest efd626923c14 7 secondes ago 105MB
Comme promis, les images basées sur Alpine se construisent plus rapidement et sont plus petites : 15 secondes au lieu de 30 et une taille d'image de 105MB contre 150MB. C'est plutÎt bien !
Mais si nous passons Ă la construction d'une application Python, ce n'est pas aussi rose.
Image Python
Les applications Python utilisent souvent pandas et matplotlib. Ainsi, une des options est de prendre l'image officielle basée sur Debian, en utilisant ce Dockerfile :
FROM python:3.8-slim
RUN pip install --no-cache-dir matplotlib pandas
Construisons-le :
$ docker build -f Dockerfile.slim -t python-matpan.
Envoi du contexte de construction au démon Docker 3.072kB
Ătape 1/2 : FROM python:3.8-slim
---> 036ea1506a85
Ătape 2/2 : RUN pip install --no-cache-dir matplotlib pandas
---> Exécution dans 13739b2a0917
Collecte de matplotlib
Téléchargement de matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl (13,1 Mo)
Collecte de pandas
Téléchargement de pandas-0.25.3-cp38-cp38-manylinux1_x86_64.whl (10,4 Mo)
...
Construction réussie b98b5dc06690
Ătiquetage rĂ©ussi python-matpan:latest
réel 0m30.297s
utilisateur 0m0.043s
systĂšme 0m0.020s
On obtient une image de 363Â Mo.
Serons-nous mieux avec Alpine ? Essayons :
FROM python:3.8-alpine
RUN pip install --no-cache-dir matplotlib pandas
$ docker build -t python-matpan-alpine -f Dockerfile.alpine .
Envoi du contexte de construction au démon Docker 3.072kB
Ătape 1/2 : FROM python:3.8-alpine
---> a0ee0c90a0db
Ătape 2/2 : RUN pip install --no-cache-dir matplotlib pandas
---> Exécution dans 6740adad3729
Collecte de matplotlib
Téléchargement de matplotlib-3.1.2.tar.gz (40,9 Mo)
ERREUR : La commande a échoué avec le code de sortie 1 :
commande : /usr/local/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/
tmp/pip-install-a3olrixa/matplotlib/setup.py'"'"'; __file__='"'"'/tmp/pip-install-a3olrixa/matplotlib/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'rn'"'"', '"'"'n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-install-a3olrixa/matplotlib/pip-egg-info
...
ERREUR : La commande a échoué avec le code de sortie 1 : python setup.py egg_info Vérifiez les journaux pour la sortie complÚte de la commande.
La commande '/bin/sh -c pip install matplotlib pandas' a renvoyé un code non nul : 1
Que se passe-t-il?
Alpine ne prend pas en charge les wheels.
Si vous regardez le build basé sur Debian, vous verrez qu'il télécharge matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl.
C'est un binaire pour wheel. Alpine, en revanche, télécharge les sources `matplotlib-3.1.2.tar.gz`, car il ne prend pas en charge les .
Pourquoi ? La plupart des distributions Linux utilisent la version GNU (glibc) de la bibliothÚque standard C, qui est en fait nécessaire à chaque programme écrit en C, y compris Python. Mais Alpine utilise `musl`, et puisque ces binaires sont destinés à `glibc`, ils ne sont tout simplement pas compatibles.
Donc, si vous utilisez Alpine, vous devez compiler tout le code écrit en C dans chaque paquet Python.
Ah oui, vous devrez chercher vous-mĂȘme la liste de toutes les dĂ©pendances Ă compiler.
Dans ce cas, nous obtenons ceci :
FROM python:3.8-alpine
RUN apk --update add gcc build-base freetype-dev libpng-dev openblas-dev
RUN pip install --no-cache-dir matplotlib pandas
Et le temps de compilation prend...
⊠25 minutes 57 secondes ! Et la taille de l'image est de 851 Mo.
Les images basées sur Alpine prennent beaucoup plus de temps à se construire, sont en soi de plus grande taille, et il vous faudra également trouver toutes les dépendances. Il est possible de réduire la taille de la construction en utilisant mais cela signifie qu'il faudra faire encore plus de travail.
Ce n'est pas tout !
Alpine peut ĂȘtre Ă l'origine de bogues inattendus Ă l'exĂ©cution.
- En théorie, musl est compatible avec glibc, mais dans la pratique, les différences peuvent causer de nombreux problÚmes. Et s'il y en a, ils ne seront certainement pas agréables. Voici quelques problÚmes qui peuvent survenir :
- Alpine a par défaut une taille de pile de thread plus petite, ce qui peut provoquer des
- Certains utilisateurs ont découvert que en raison de la maniÚre dont musl alloue la mémoire (différente de glibc).
- Un utilisateur
Ces bogues ont sûrement déjà été corrigés, mais qui sait combien d'autres il en reste.
N'utilisez pas d'images Alpine pour Python.
Si vous ne voulez pas vous compliquer la tùche avec de grandes et longues constructions, à chercher des dépendances et à faire face à des bogues potentiels - n'utilisez pas Alpine Linux comme image de base. .
Source : habr.com
