Alpine compila imágenes de Docker para Python 50 veces más lento y las imágenes son 2 veces más grandes.

Alpine compila imágenes de Docker para Python 50 veces más lento y las imágenes son 2 veces más grandes.

Alpine Linux es a menudo recomendado como imagen base para Docker. Se dice que usar Alpine hará que tus compilaciones sean más pequeñas y el proceso de compilación más rápido.

Pero si usas Alpine Linux para aplicaciones de Python, entonces:

  • Hace que tus compilaciones sean mucho más lentas.
  • Hace que tus imágenes sean más grandes.
  • Te cuesta tiempo.
  • Y, al final, puede ser la causa de errores en tiempo de ejecución.


Veamos por qué se recomienda Alpine, pero por qué aún así no deberías usarlo junto con Python.

¿Por qué la gente recomienda Alpine?

Supongamos que necesitamos gcc como parte de nuestra imagen y queremos comparar Alpine Linux con Ubuntu 18.04 en términos de velocidad de compilación y tamaño final de la imagen.

Primero, descarguemos ambas imágenes y comparemos su tamaño:

$ 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 puedes ver, la imagen base para Alpine es mucho más pequeña. Ahora intentemos instalar gcc y comenzaremos 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 un Dockerfile perfecto está más allá del alcance de este artículo.

Mediremos la velocidad de compilación:

$ 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 lo mismo para Alpine (Dockerfile):

FROM alpine
RUN apk add --update gcc

Compilamos, observamos el tiempo y el tamaño de la compilación:

$ 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 se prometió, las imágenes basadas en Alpine se compilan más rápido y son más pequeñas: 15 segundos en lugar de 30 y un tamaño de imagen de 105MB frente a 150MB. ¡Eso es bastante bueno!

Pero si cambiamos a la compilación de una aplicación de Python, las cosas no son tan brillantes.

Imagen de Python

Las aplicaciones de Python a menudo utilizan pandas y matplotlib. Por lo tanto, una de las opciones es tomar la imagen oficial basada en Debian, utilizando un Dockerfile como este:

FROM python:3.8-slim
RUN pip install --no-cache-dir matplotlib pandas

La compilamos:

$ docker build -f Dockerfile.slim -t python-matpan.
Enviando contexto de construcción al demonio de Docker  3.072kB
Paso 1/2 : FROM python:3.8-slim
 ---> 036ea1506a85
Paso 2/2 : RUN pip install --no-cache-dir matplotlib pandas
 ---> Ejecutando en 13739b2a0917
Recolección de matplotlib
  Descargando matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl (13.1 MB)
Recolección de pandas
  Descargando pandas-0.25.3-cp38-cp38-manylinux1_x86_64.whl (10.4 MB)
...
Construcción exitosa b98b5dc06690
Etiquetado exitosamente python-matpan:latest

real    0m30.297s
user    0m0.043s
sys     0m0.020s

Estamos obteniendo una imagen de 363MB.
¿Lo haremos mejor con Alpine? Vamos a intentarlo:

FROM python:3.8-alpine
RUN pip install --no-cache-dir matplotlib pandas

$ docker build -t python-matpan-alpine -f Dockerfile.alpine .                                 
Enviando contexto de construcción al demonio de Docker  3.072kB                                               
Paso 1/2 : FROM python:3.8-alpine                                                             
 ---> a0ee0c90a0db                                                                            
Paso 2/2 : RUN pip install --no-cache-dir matplotlib pandas                                                  
 ---> Ejecutando en 6740adad3729                                                                 
Recolección de matplotlib                                                                         
  Descargando matplotlib-3.1.2.tar.gz (40.9 MB)                                               
    ERROR: El comando terminó con el estado 1:                                            
     comando: /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: El comando terminó con estado 1: python setup.py egg_info Verifique los registros para la salida completa del comando.
El comando '/bin/sh -c pip install matplotlib pandas' devolvió un código distinto de cero: 1

¿Qué está pasando?

Alpine no admite wheels

Si miras la construcción que se basa en Debian, verás que descarga matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl.

Es un binario para wheels. Alpine, en cambio, descarga los fuentes `matplotlib-3.1.2.tar.gz`, ya que no admite los estándar wheels.

¿Por qué? La mayoría de las distribuciones de Linux utilizan la versión GNU (glibc) de la biblioteca estándar C, que en realidad es necesaria para cada programa escrito en C, incluyendo Python. Pero Alpine utiliza `musl`, y dado que esos binarios están destinados a `glibc`, simplemente no son una opción.

Por lo tanto, si estás usando Alpine, necesitarás compilar todo el código escrito en C en cada paquete de Python.

Ah, sí, tendrás que buscar tú mismo la lista de todas esas dependencias que necesitas compilar.
En este caso, obtenemos lo siguiente:

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

Y el tiempo de construcción toma…

… 25 minutos 57 segundos! Y el tamaño de la imagen es 851MB.

Las imágenes basadas en Alpine se construyen mucho más lentamente, son más grandes y además necesitas buscar todas las dependencias. Claro, se puede reducir el tamaño de la construcción utilizando construcciones de múltiples etapas , pero eso significa que hay que hacer mucho más trabajo.

¡Eso no es todo!

Alpine puede ser la causa de errores inesperados en tiempo de ejecución.

Seguramente esos errores ya se han corregido, pero quién sabe cuántos más hay.

No utilices imágenes de Alpine para Python.

Si no quieres lidiar con construcciones grandes y largas, buscar dependencias y errores potenciales, no uses Alpine Linux como imagen base. Elegir una buena imagen base..

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster