He creado una aplicación de Python que se conecta a la API de Forem para obtener una lista de artículos que he escrito en DEV, y muestra los resultados en un página web construida con Flask. El código fuente está disponible en un repositorio de GitLab.
Para contenerizar esta aplicación con Docker, se debe crear un Dockerfile
con el siguiente contenido:
FROM python:latest
WORKDIR /app
COPY requirements.txt .
RUN pip install --upgrade pip --no-cache-dir
RUN pip install -r requirements.txt --no-cache-dir
COPY . .
EXPOSE 8080
ENTRYPOINT ["gunicorn","--config", "gunicorn_config.py", "app:app"]
Ahora se debe construir la imagen ejecutando:
$ docker build . -t blog
Si ejecutas el siguiente comando:
$ docker image ls blog
Obtendrás la siguiente salida:
REPOSITORY TAG IMAGE ID CREATED SIZE
blog latest 3debcac78e45 20 minutes ago 1.05GB
El tamaño de la imagen es. ¿Cómo optimizar la imagen de Docker?
Hay algunos enfoques que pueden analizarse:
- Usar imágenes base más pequeñas
- Construcciones de múltiples etapas
A través de este artículo, aprenderás como optimizar tu imagen de Docker a través de ambas soluciones.
Usar Imágenes Base Más Pequeñas#
Usar una imagen base más pequeña puede ayudar a reducir el tamaño de la imagen. Reemplaza la imagen python:latest
con la imagen python:alpine3.19
:
FROM python:alpine3.19
WORKDIR /app
COPY requirements.txt .
RUN pip install --upgrade pip --no-cache-dir
RUN pip install -r requirements.txt --no-cache-dir
COPY . .
EXPOSE 8080
ENTRYPOINT ["gunicorn","--config", "gunicorn_config.py", "app:app"]
Construye la imagen:
$ docker build . -t blog
Ejecuta el siguiente comando:
$ docker image ls blog
Esta es la salida que obtienes:
REPOSITORY TAG IMAGE ID CREATED SIZE
blog latest 2b3085ad2c5d 19 seconds ago 81.1MB
Como puedes ver, el tamaño de la imagen se reduce de 1.05GB
a 81.1MB
.
Construcciones de Múltiples Etapas#
Escribí sobre como usar las construcciones de múltiples etapas para optimizar una aplicación Rust contenerizada, y como se explica acá, esta solución puede funcionar para aplicaciones Python.
Crea un Dockerfile
como se muestra, con construcciones de múltiples etapas y venv:
FROM python:alpine3.19 as builder
ENV PATH="/app/venv/bin:$PATH"
WORKDIR /app
RUN python -m venv /app/venv
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
FROM python:alpine3.19
WORKDIR /app
ENV PATH="/app/venv/bin:$PATH"
COPY . .
COPY --from=builder /app/venv /app/venv
ENTRYPOINT ["gunicorn", "--config", "gunicorn_config.py", "app:app"]
Contruye la imagen:
$ docker build . -t blog
Ejecuta el siguiente comando:
$ docker image ls blog
Esta es la salida que obtienes:
REPOSITORY TAG IMAGE ID CREATED SIZE
blog latest 2b3085ad2c5d 19 seconds ago 76.2MB
Esta imagen se redujo un poco más, comparado con el resultado obtenido cuando solo se usa una imagen más pequeña.
Conclusión#
A través de este artículos, aprendiste como optimizar tu aplicación Python contenerizada, mediante diferentes soluciones, y combinando todas las prácticas descritas acá.