Dockerfile respectivospython3.9 , latest (Dockerfile) Estas etiquetas ya no son compatibles o mantenidas, se eliminan del repositorio de GitHub, pero las últimas versiones empujadas aún podrían estar disponibles en Docker Hub si alguien las ha estado tirando:
python3.9-alpine3.13python3.8python3.8-alpine3.11python3.7python3.7-alpine3.8python3.6python3.6-alpine3.8python2.7Las últimas etiquetas de fecha para estas versiones son:
python3.9-alpine3.13-2024-03-11python3.8-2024-10-28python3.8-alpine3.11-2024-03-11python3.7-2024-10-28python3.7-alpine3.8-2024-03-11python3.6-2022-11-25python3.6-alpine3.8-2022-11-25python2.7-2022-11-25 Nota : Hay etiquetas para cada fecha de compilación. Si necesita "fijar" la versión de imagen de Docker que usa, puede seleccionar una de esas etiquetas. Por ejemplo, tiangolo/meinheld-gunicorn-flask:python3.9-2024-11-02 .
Imagen de Docker con Meinheld administrado por Gunicorn para aplicaciones web de alto rendimiento en Flask usando Python con ajuste automático de rendimiento.
Repo de Github : https://github.com/tiangolo/meinheld-gunicorn-flask-docker
Imagen de Docker Hub : https://hub.docker.com/r/tiangolo/meinheld-gunicorn-flask/
Las aplicaciones web de Python Flask que se ejecutan con Meinheld controladas por Gunicorn tienen algunas de las mejores actuaciones logrables por Flask (*).
Si tiene una aplicación ya existente en Flask o está construyendo una nueva, esta imagen le dará el mejor rendimiento posible (o cerca de eso).
Esta imagen tiene un mecanismo de "ajuste automático" incluido, para que pueda agregar su código y obtener un buen rendimiento automáticamente. Y sin hacer sacrificios (como el registro).
La última versión actual de Meinheld lanzada es 1.0.2, del 17 de mayo de 2020. Esta versión de Meinheld requiere una versión anterior de Greenlet ( >=0.4.5,<0.5 ) que no es compatible con Python 3.10 y 3.11. Es por eso que la última versión de Python compatible con esta imagen es Python 3.9.
Si está comenzando un nuevo proyecto, puede beneficiarse de un marco más nuevo y más rápido como Fastapi (basado en ASGI en lugar de WSGI como Flask y Django), y una imagen de Docker como Tiangolo/Uvicorn-Gunicorn-Fastapi .
Le daría alrededor del 200% el rendimiento que se puede lograr con Flask, incluso cuando se usa esta imagen.
Además, si desea utilizar nuevas tecnologías como WebSockets, sería más fácil con un marco más nuevo basado en ASGI, como Fastapi . Como el ASGI estándar fue diseñado para poder manejar el código asíncrono como el necesario para WebSockets.
Meinheld es un servidor web compatible con WSGI de alto rendimiento.
Puede usar Gunicorn para administrar Meinheld y ejecutar múltiples procesos de él.
Flask es un microframework para Python basado en Werkzeug, Jinja 2 y buenas intenciones.
Esta imagen fue creada para ser una alternativa a Tiangolo/UWSGI-NGINX-Flask , proporcionando aproximadamente el 400% el rendimiento de esa imagen.
Se basa en la imagen más genérica Tiangolo/Meinheld-Gunicorn . Ese es el que usarías para otros marcos WSGI, como Django.
Probablemente esté usando Kubernetes o herramientas similares. En ese caso, probablemente no necesite esta imagen (o ninguna otra imagen base similar ). Probablemente sea mejor construyendo una imagen de Docker desde cero .
Si tiene un clúster de máquinas con Kubernetes , Docker Swarm Mode, Nomad u otro sistema complejo similar para administrar contenedores distribuidos en múltiples máquinas, entonces probablemente desee manejar la replicación a nivel de clúster en lugar de usar un administrador de procesos en cada contenedor que inicia múltiples procesos de trabajadores , que es lo que hace esta imagen Docker.
En esos casos (por ejemplo, con Kubernetes), probablemente querrá construir una imagen Docker desde cero , instalar sus dependencias y ejecutar un solo proceso en lugar de esta imagen.
Por ejemplo, con Gunicorn, puede tener una app/gunicorn_conf.py con:
# Gunicorn config variables
loglevel = "info"
errorlog = "-" # stderr
accesslog = "-" # stdout
worker_tmp_dir = "/dev/shm"
graceful_timeout = 120
timeout = 120
keepalive = 5
threads = 3 Y luego podrías tener un Dockerfile con:
FROM python:3.9
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
CMD [ "gunicorn" , "--conf" , "app/gunicorn_conf.py" , "--bind" , "0.0.0.0:80" , "app.main:app" ]Puede leer más sobre estas ideas en la documentación de Fastapi sobre: Fastapi en contenedores: Docker, ya que las mismas ideas se aplicarían a otras aplicaciones web en contenedores.
Puede desear un administrador de procesos que ejecute múltiples procesos de trabajadores en el contenedor si su aplicación es lo suficientemente simple como para no necesitar (al menos aún no) para ajustar demasiado la cantidad de procesos, y puede usar un valor predeterminado automatizado, y la está ejecutando en un solo servidor , no un clúster.
Podría estar implementando en un solo servidor (no un clúster) con Docker Compose , por lo que no tendría una manera fácil de administrar la replicación de contenedores (con Docker Compose) mientras preserva la red compartida y el equilibrio de carga .
Luego, podría tener un solo contenedor con un administrador de procesos que inicie varios procesos de trabajadores en el interior, como lo hace esta imagen Docker.
También podría tener otras razones que facilitarían tener un solo contenedor con múltiples procesos en lugar de tener múltiples contenedores con un solo proceso en cada uno de ellos.
Por ejemplo (dependiendo de su configuración), podría tener alguna herramienta como un exportador de Prometheus en el mismo contenedor que debería tener acceso a cada una de las solicitudes que vienen.
En este caso, si tuviera múltiples contenedores , de forma predeterminada, cuando Prometheus llegó a leer las métricas , obtendría los que se encuentran para un solo contenedor cada vez (para el contenedor que manejaba esa solicitud en particular), en lugar de obtener las métricas acumuladas para todos los contenedores replicados.
Luego, en ese caso, podría ser más simple tener un contenedor con múltiples procesos y una herramienta local (por ejemplo, un exportador de Prometheus) en el mismo contenedor que recolecta métricas Prometheus para todos los procesos internos y expone esas métricas en ese contenedor único.
Lea más sobre todo en la documentación de Fastapi sobre: Fastapi en contenedores - Docker, ya que los mismos conceptos se aplican a otras aplicaciones web en contenedores.
No tienes que clonar este repositorio.
Puede usar esta imagen como imagen base para otras imágenes.
Suponiendo que tenga un archivo requirements.txt , podría tener un Dockerfile como este:
FROM tiangolo/meinheld-gunicorn-flask:python3.9
COPY ./requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY ./app /app Esperará un archivo en /app/app/main.py .
O de lo contrario, un archivo en /app/main.py .
Y esperará que contenga una app variable con su aplicación "WSGI".
Luego puede construir su imagen desde el directorio que tiene su Dockerfile , por ejemplo:
docker build -t myimage ./Estas son las variables de entorno que puede configurar en el contenedor para configurarlo y sus valores predeterminados:
MODULE_NAMEEl "módulo" (archivo) de Python para ser importado por Gunicorn, este módulo contendría la aplicación de matraz real en una variable.
Por defecto:
app.main si hay un archivo /app/app/main.py omain si hay un archivo /app/main.py Por ejemplo, si su archivo principal estaba en /app/custom_app/custom_main.py , podría configurarlo como:
docker run -d -p 80:80 -e MODULE_NAME= " custom_app.custom_main " myimageVARIABLE_NAMELa variable dentro del módulo Python que contiene la aplicación Flask.
Por defecto:
appPor ejemplo, si su archivo principal de Python tiene algo como:
from flask import Flask
api = Flask ( __name__ )
@ api . route ( "/" )
def hello ():
return "Hello World from Flask" En este caso, api sería la variable con la "aplicación frascos". Podrías configurarlo como:
docker run -d -p 80:80 -e VARIABLE_NAME= " api " myimageAPP_MODULELa cadena con el módulo Python y el nombre de la variable pasaron a Gunicorn.
De forma predeterminada, establezca en función de las variables MODULE_NAME y VARIABLE_NAME :
app.main:app omain:appPuedes configurarlo como:
docker run -d -p 80:80 -e APP_MODULE= " custom_app.custom_main:api " myimageGUNICORN_CONFLa ruta a un archivo de configuración de Gunicorn Python.
Por defecto:
/app/gunicorn_conf.py si existe/app/app/gunicorn_conf.py si existe/gunicorn_conf.py (el valor predeterminado incluido)Puedes configurarlo como:
docker run -d -p 80:80 -e GUNICORN_CONF= " /app/custom_gunicorn_conf.py " myimageWORKERS_PER_COREEsta imagen verificará cuántos núcleos de CPU están disponibles en el servidor actual que ejecuta su contenedor.
Establecerá el número de trabajadores en el número de núcleos de CPU multiplicados por este valor.
Por defecto:
2Puedes configurarlo como:
docker run -d -p 80:80 -e WORKERS_PER_CORE= " 3 " myimage Si utilizara el valor 3 en un servidor con 2 núcleos de CPU, ejecutaría 6 procesos de trabajadores.
También puede usar valores de punto flotante.
Entonces, por ejemplo, si tiene un gran servidor (digamos, con 8 núcleos de CPU) que ejecuta varias aplicaciones, y tiene una aplicación ASGI que sabe que no necesitará alto rendimiento. Y no desea desperdiciar recursos del servidor. Podría hacer que use 0.5 trabajadores por núcleo de CPU. Por ejemplo:
docker run -d -p 80:80 -e WORKERS_PER_CORE= " 0.5 " myimageEn un servidor con 8 núcleos de CPU, esto haría que inicie solo 4 procesos de trabajadores.
WEB_CONCURRENCYAnular la definición automática del número de trabajadores.
Por defecto:
WORKERS_PER_CORE . Entonces, en un servidor con 2 núcleos, de forma predeterminada se establecerá en 4 .Puedes configurarlo como:
docker run -d -p 80:80 -e WEB_CONCURRENCY= " 2 " myimageEsto haría que la imagen inicie 2 procesos de trabajadores, independientemente de cuántos núcleos de CPU están disponibles en el servidor.
HOSTEl "anfitrión" utilizado por Gunicorn, la IP donde Gunicorn escuchará las solicitudes.
Es el host dentro del contenedor.
Entonces, por ejemplo, si establece esta variable en 127.0.0.1 , solo estará disponible dentro del contenedor, no en el host que lo ejecuta.
Se proporciona para completar, pero probablemente no debería cambiarlo.
Por defecto:
0.0.0.0PORTEl puerto del contenedor debe escuchar.
Si está ejecutando su contenedor en un entorno restrictivo que lo obliga a usar un puerto específico (como 8080 ), puede configurarlo con esta variable.
Por defecto:
80Puedes configurarlo como:
docker run -d -p 80:8080 -e PORT= " 8080 " myimageBINDEl anfitrión y el puerto reales pasaron a Gunicorn.
Por defecto, establezca en función HOST y PORT las variables.
Entonces, si no cambió nada, se establecerá de forma predeterminada para:
0.0.0.0:80Puedes configurarlo como:
docker run -d -p 80:8080 -e BIND= " 0.0.0.0:8080 " myimageLOG_LEVELEl nivel de registro para Gunicorn.
Uno de:
debuginfowarningerrorcritical Por defecto, configure en info .
Si necesita exprimir más registro de sacrificio de rendimiento, configúrelo en warning , por ejemplo:
Puedes configurarlo como:
docker run -d -p 80:8080 -e LOG_LEVEL= " warning " myimage Los registros se envían al stderr y stdout del contenedor, lo que significa que puede ver los registros con los docker logs -f your_container_name_here .
La imagen incluye un archivo de configuración predeterminado de Gunicorn Python en /gunicorn_conf.py .
Utiliza las variables de entorno declaradas anteriormente para establecer todas las configuraciones.
Puede anularlo incluyendo un archivo en:
/app/gunicorn_conf.py/app/app/gunicorn_conf.py/gunicorn_conf.py/app/prestart.sh Si necesita ejecutar algo antes de comenzar la aplicación, puede agregar un archivo prestart.sh al directorio /app . La imagen detectará y ejecutará automáticamente antes de comenzar todo.
Por ejemplo, si desea agregar migraciones SQL alembic (con sqlalchemy), puede crear un archivo ./app/prestart.sh en su directorio de código (que será copiado por su Dockerfile ) con:
#! /usr/bin/env bash
# Let the DB start
sleep 10 ;
# Run migrations
alembic upgrade head Y esperaría 10 segundos para darle a la base de datos algo de tiempo para comenzar y luego ejecutar ese comando alembic .
Si necesita ejecutar un script de Python antes de comenzar la aplicación, puede hacer que el archivo /app/prestart.sh ejecute su script Python, con algo así como:
#! /usr/bin/env bash
# Run custom Python script before starting
python /app/my_custom_prestart_script.py En resumen: probablemente no debería usar Alpine para proyectos de Python, sino que use las versiones de imagen slim Docker.
¿Quieres más detalles? ¿Continuar leyendo?
Alpine es más útil para otros idiomas donde construye un binario estático en una etapa de imagen de Docker (usando el edificio Docker de varias etapas) y luego copie a una imagen alpina simple, y luego simplemente ejecute ese binario. Por ejemplo, usando Go.
Pero para Python, ya que Alpine no usa las herramientas estándar utilizadas para construir extensiones de Python, al instalar paquetes, en muchos casos Python ( pip ) no encontrará un paquete instalable precompilado (una "rueda") para alpine. Y después de depurar muchos errores extraños, se dará cuenta de que debe instalar muchas herramientas adicionales y construir muchas dependencias solo para usar algunos de estos paquetes de Python comunes. ?
Esto significa que, aunque la imagen alpina original podría haber sido pequeña, termina con una imagen con un tamaño comparable al tamaño que habría obtenido si hubiera usado una imagen de Python estándar (basada en Debian) o en algunos casos aún más grande. ?
Y en todos esos casos, llevará mucho más tiempo construir, consumir muchos más recursos, construir dependencias durante más tiempo y también aumentar su huella de carbono, ya que está utilizando más tiempo y energía de CPU para cada construcción. ?
Si desea imágenes delgadas de Python, debe intentar usar las versiones slim que todavía se basan en Debian, pero que son más pequeñas. ?
Se prueban todas las etiquetas de imagen, configuraciones, variables de entorno y opciones de aplicación.
issue-manager.yml . PR #154 por @Tiangolo.latest-changes . PR #153 por @Tiangolo.latest-changes.yml . PR #141 por @alejsdev.README.md . PR #137 por @alejsdev. Lo más destacado de este lanzamiento:
Soporte para Python 3.9 y 3.8.
Depreción de Python 3.6 y 2.7.
python3.6-2022-11-25 y python2.7-2022-11-25 .Versiones actualizadas de todas las dependencias.
Pequeñas mejoras y soluciones.
Agregue soporte para Python 3.9 y Python 3.9 Alpine. PR #50 por @Tiangolo.
Agregue Python 3.8 con Alpine 3.11. PR #28.
Agregue soporte para Python 3.8. PR #27.
tiangolo/meinheld-gunicorn-flask:python3.7-2019-10-15 . PR #17.Agregue soporte para Python 2.7 (debe usar Python 3.7 o Python 3.6). PR #11.
Actualizar la configuración de Travis CI. PR #10 por @cclauss.
/app/prestart.sh . Este proyecto tiene licencia bajo los términos de la licencia MIT.