Volver al inicio

Optimización de Python Docker: -43-57% tamaño

El artículo desglosa la optimización de imágenes Python Docker: multi-stage build reduce el tamaño en un 43%, scratch — en un 57%. Ejemplos de Dockerfile, benchmarks, análisis con dive. Adecuado para desarrolladores middle/senior.

Python Docker: tamaño -57% desde scratch con multi-stage
Advertisement 728x90

Optimización de Imágenes Docker en Python: Reducción del Tamaño en un 43–57%

Las compilaciones multi-etapa y las imágenes slim de Python pueden reducir el tamaño de la imagen de ejecución de 895 MB a 508 MB (-43%). El tiempo de compilación tras cambios en el código baja de 56 a 16 segundos. Esto acelera los despliegues en Kubernetes, ahorra almacenamiento y reduce el tráfico.

La optimización aborda problemas clave: escalado rápido de pods durante picos de tráfico y reducción de la latencia para el usuario. Las dependencias se gestionan con Poetry, y las pruebas se ejecutan en la etapa de construcción.

.dockerignore e Imágenes Slim

Excluye pruebas y archivos innecesarios mediante .dockerignore. Las pruebas solo son necesarias durante la etapa de construcción.

Google AdInline article slot

Cambia a python:3.13-slim-bookworm. La imagen completa añade cientos de MB.

Deshabilita la caché de pip/Poetry con flags:

  • pip: --no-cache-dir
  • Poetry: poetry cache clear --all pypi

Compilación Multi-Etapa: Análisis del Dockerfile

La etapa de construcción instala Poetry, las dependencias y ejecuta pytest. La etapa de ejecución copia solo site-packages, binarios (gunicorn, uvicorn) y el código.

Google AdInline article slot
# Etapa de construcción
FROM python:3.13-slim-bookworm AS builder
ENV PYTHONUNBUFFERED=1 \
    LANG=C.UTF-8 \
    PYTHONDONTWRITEBYTECODE=1

RUN apt-get update -qq && \
    apt-get install -y --no-install-recommends \
      curl \
      gcc \
      libc-dev \
    && pip install --no-cache-dir 'poetry==2.3.2' \
    && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

WORKDIR /code

COPY pyproject.toml poetry.lock* ./

RUN poetry config virtualenvs.create false \
  && poetry install --no-root --no-dev --no-interaction --no-ansi \
  && poetry cache clear --all pypi --no-interaction || true \
  && rm -rf ~/.cache/pip

COPY . .
RUN pytest

# Etapa de ejecución
FROM python:3.13-slim-bookworm
ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    LANG=C.UTF-8

WORKDIR /code

COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
COPY --from=builder /usr/local/bin/gunicorn /usr/local/bin/gunicorn
COPY --from=builder /usr/local/bin/uvicorn /usr/local/bin/uvicorn

COPY --from=builder /code /code

Resultados Básicos de Optimización:

| Métrica | Antes | Después | Cambio |

|---------|------|-------|-----------|

Google AdInline article slot

| Tamaño Imagen, MB | 894.84 | 508 | -43% |

| Tiempo Compilación Completa, s | 58 | 315 | +443% |

| Tiempo Compilación Tras Ediciones, s | 56 | 16 | -71% |

La primera compilación es más lenta debido a las capas del constructor, pero el caché acelera las iteraciones.

Métodos Avanzados: Chainguard y Análisis Manual

Imágenes Chainguard

Chainguard excluye shell, apt/apk, minimizando la superficie de ataque. Sin CVEs en imágenes base. Ahorro: 50–150 MB.

Desventajas:

  • Depuración sin shell
  • Gratis solo para la etiqueta latest
  • Versiones de pago son caras

Adecuado para proyectos de alta seguridad.

Análisis Manual con dive

Analiza capas:

docker history --format "{{.CreatedBy}}: {{.Size}}" image:tag
docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive:latest image:tag

Enfócate en capas de ejecución grandes. Colapsa directorios (Shift+Espacio), elimina librerías innecesarias. Requiere experiencia en Linux, rara vez vale la pena.

Optimización Extrema: scratch

Ejecución en scratch—copia solo la libc necesaria. El tamaño baja a 384 MB (-57% del original, -24% de multi-etapa).

Desventajas:

  • Depuración imposible
  • Nuevas dependencias requieren añadir librerías manualmente
  • Tiempo de depuración: 1+ hora

Relevante para miles de pods, Serverless (Knative, Fargate). Más difícil en Python que en Go.

Comparación de Tamaño:

  • Sin multi-etapa: 894 → 384 MB (-57%)
  • Multi-etapa: 508 → 384 MB (-24%)

Optimización del Tiempo de Compilación

Copia pyproject.toml/poetry.lock ANTES del código:

  • COPY pyproject.toml poetry.lock* ./
  • RUN poetry install
  • COPY . .
  • RUN pytest

El caché de dependencias persiste con cambios en el código. Aceleración: 58 → 14 s (x4).

Conclusiones Clave

  • Multi-etapa + slim: -43% tamaño, -71% tiempo de iteración.
  • .dockerignore + no-cache: excluye pruebas y caché del entorno de ejecución.
  • Orden de COPY: dependencias cacheadas separadas del código.
  • Scratch: -57%, pero para casos extremos (miles de pods).
  • Chainguard/dive: para seguridad y ajuste fino.

— Editorial Team

Advertisement 728x90

Leer después