ProHoster > Blog > Administración > Alpine compila as compilacións de Docker para Python 50 veces máis lenta e as imaxes son dúas veces máis pesadas
Alpine compila as compilacións de Docker para Python 50 veces máis lenta e as imaxes son dúas veces máis pesadas
Alpine Linux adoita recomendarse como imaxe base para Docker. Díxenche que usar Alpine fará que as túas construcións sexan máis pequenas e que o teu proceso de construción sexa máis rápido.
Pero se usa Alpine Linux para aplicacións Python, entón:
Fai que as túas construcións sexan moito máis lentas
Fai as túas imaxes máis grandes
Perder o tempo
E ao final pode causar erros no tempo de execución
Vexamos por que se recomenda Alpine, pero por que aínda non deberías usalo con Python.
Por que a xente recomenda Alpine?
Supoñamos que necesitamos gcc como parte da nosa imaxe e queremos comparar Alpine Linux con Ubuntu 18.04 en termos de velocidade de compilación e tamaño da imaxe final.
En primeiro lugar, descarguemos dúas imaxes e comparemos os seus tamaños:
$ 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
Como podes ver, a imaxe base de Alpine é moito máis pequena. Imos agora tentar instalar gcc e comezar con 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/*
Escribir o Dockerfile perfecto está fóra do alcance deste artigo.
Imos medir a velocidade de montaxe:
$ time docker build -t ubuntu-gcc -f Dockerfile.ubuntu --quiet .
sha256:b6a3ee33acb83148cd273b0098f4c7eed01a82f47eeb8f5bec775c26d4fe4aae
real 0m29.251s
user 0m0.032s
sys 0m0.026s
$ docker image ls ubuntu-gcc
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu-gcc latest b6a3ee33acb8 9 seconds ago 150MB
Repetimos o mesmo para Alpine (Dockerfile):
FROM alpine
RUN apk add --update gcc
Montamos, miramos a hora e o tamaño da montaxe:
$ time docker build -t alpine-gcc -f Dockerfile.alpine --quiet .
sha256:efd626923c1478ccde67db28911ef90799710e5b8125cf4ebb2b2ca200ae1ac3
real 0m15.461s
user 0m0.026s
sys 0m0.024s
$ docker image ls alpine-gcc
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine-gcc latest efd626923c14 7 seconds ago 105MB
Como prometeu, as imaxes baseadas en Alpine recóllense máis rápido e son máis pequenas: 15 segundos en lugar de 30 e o tamaño da imaxe é de 105 MB fronte a 150 MB. Está moi ben!
Pero se cambiamos a construír unha aplicación Python, entón todo non é tan bo.
Imaxe de Python
As aplicacións de Python adoitan usar pandas e matplotlib. Polo tanto, unha opción é tomar a imaxe oficial baseada en Debian usando este Dockerfile:
FROM python:3.8-slim
RUN pip install --no-cache-dir matplotlib pandas
Imos recollelo:
$ docker build -f Dockerfile.slim -t python-matpan.
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM python:3.8-slim
---> 036ea1506a85
Step 2/2 : RUN pip install --no-cache-dir matplotlib pandas
---> Running in 13739b2a0917
Collecting matplotlib
Downloading matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl (13.1 MB)
Collecting pandas
Downloading pandas-0.25.3-cp38-cp38-manylinux1_x86_64.whl (10.4 MB)
...
Successfully built b98b5dc06690
Successfully tagged python-matpan:latest
real 0m30.297s
user 0m0.043s
sys 0m0.020s
Temos unha imaxe de 363 MB de tamaño.
Farémolo mellor con Alpine? Imos probar:
FROM python:3.8-alpine
RUN pip install --no-cache-dir matplotlib pandas
$ docker build -t python-matpan-alpine -f Dockerfile.alpine .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM python:3.8-alpine
---> a0ee0c90a0db
Step 2/2 : RUN pip install --no-cache-dir matplotlib pandas
---> Running in 6740adad3729
Collecting matplotlib
Downloading matplotlib-3.1.2.tar.gz (40.9 MB)
ERROR: Command errored out with exit status 1:
command: /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
...
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
The command '/bin/sh -c pip install matplotlib pandas' returned a non-zero code: 1
Que pasa?
Alpine non admite rodas
Se miras a compilación, que está baseada en Debian, verás que descarga matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl.
Este é un binario para roda. Alpine descarga as fontes `matplotlib-3.1.2.tar.gz` xa que non admite estándar rodas.
Por que? A maioría das distribucións de Linux usan a versión GNU (glibc) da biblioteca estándar C, que de feito é requirida por todos os programas escritos en C, incluído Python. Pero Alpine usa `musl`, e dado que eses binarios están deseñados para `glibc`, simplemente non son unha opción.
Polo tanto, se usas Alpine, necesitas compilar todo o código escrito en C en cada paquete de Python.
Ah, si, terás que buscar a lista de todas esas dependencias que hai que compilar vostede mesmo.
Neste caso obtemos isto:
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
E o tempo de construción leva...
... 25 minutos 57 segundos! E o tamaño da imaxe é de 851 MB.
As imaxes baseadas no alpino tardan moito máis en construírse, son de maior tamaño e aínda debes buscar todas as dependencias. Por suposto, pode reducir o tamaño da montaxe usando construcións en varias etapas pero iso significa que aínda hai que traballar máis.
Isto non é todo!
Alpine pode causar erros inesperados no tempo de execución
En teoría, musl é compatible con glibc, pero na práctica as diferenzas poden causar moitos problemas. E se o son, probablemente serán desagradables. Aquí tes algúns problemas que poden ocorrer:
Alpine ten un tamaño de pila de fíos menor por defecto, o que pode provocar erros en Python
Seguro que estes erros xa foron corrixidos, pero quen sabe cantos máis haberá.
Non use imaxes alpinas para Python
Se non queres molestarte con compilacións grandes e longas, buscando dependencias e posibles erros, non uses Alpine Linux como imaxe base. Elixir unha boa imaxe base.