Dockerfile respectifspython3.12 , latest (dockerfile)python3.11 , (dockerfile)python3.10 , (dockerfile)python3.9 , (dockerfile) Ces balises ne sont plus prises en charge ou entretenues, elles sont supprimées du référentiel GitHub, mais les dernières versions poussées pourraient toujours être disponibles dans Docker Hub si quelqu'un les tire:
python3.8python3.8-alpinepython3.7python3.6python2.7Les étiquettes de dernière date pour ces versions sont:
python3.8-2024-10-28python3.8-alpine-2024-03-11python3.7-2024-10-28python3.6-2022-11-25python2.7-2022-11-25 Remarque : il y a des balises pour chaque date de construction. Si vous devez "épingler" la version Docker Image que vous utilisez, vous pouvez sélectionner l'une de ces balises. Par exemple tiangolo/uwsgi-nginx:python3.12-2024-11-02 .
Image Docker avec UWSGI et NGINX pour les applications Web dans Python (comme Flask ) dans un seul conteneur.
Cette image Docker vous permet de créer des applications Web Python qui s'exécutent avec UWSGI et Nginx dans un seul conteneur.
La combinaison de UWSGI avec Nginx est un moyen courant de déployer des applications Web Python comme Flask et Django. Il est largement utilisé dans l'industrie et vous donnerait des performances décentes. (*)
Cette image a été créée pour être l'image de base pour Tiangolo / UWSGI-nginx-FLASK mais pourrait être utilisée comme image de base pour toute autre application Web Python (basée sur WSGI), comme Django.
Si vous démarrez un nouveau projet, vous pourriez bénéficier d'un cadre plus récent et plus rapide basé sur ASGI au lieu de WSGI (Flask et Django sont basés sur WSGI).
Vous pouvez utiliser un framework ASGI comme:
Fastapi, ou Starlette, vous donnerait environ 800% (8x) la performance réalisable avec cette image ( Tiangolo / Uwsgi-nginx ). Vous pouvez voir les repères tiers ici.
De plus, si vous souhaitez utiliser de nouvelles technologies comme WebSockets, ce serait plus facile (et possible ) avec un cadre plus récent basé sur ASGI, comme Fastapi ou Starlette. Comme l'ASGI standard a été conçu pour être en mesure de gérer le code asynchrone comme celui nécessaire pour WebSockets.
Si vous avez besoin d'utiliser un cadre basé sur WSGI plus ancien comme Flask ou Django (au lieu de quelque chose basé sur ASGI) et que vous devez avoir les meilleures performances possibles, vous pouvez utiliser l'image alternative: Tiangolo / Meinheld-Gunicorn .
Tiangolo / Meinheld-Gunicorn vous donnera environ 400% (4x) les performances de cette image.
Github Repo : https://github.com/tiangolo/uwsgi-nginx-docker
Image Docker Hub : https://hub.docker.com/r/tiangolo/uwsgi-nginx/
Vous utilisez probablement des kubernetes ou des outils similaires. Dans ce cas, vous n'avez probablement pas besoin de cette image (ou de toute autre image de base similaire ). Vous feriez probablement mieux de construire une image Docker à partir de zéro .
Si vous avez un groupe de machines avec Kubernetes , Mode Swarm Docker, Nomad ou autre système complexe similaire pour gérer des conteneurs distribués sur plusieurs machines, vous voudrez probablement gérer la réplication au niveau du cluster au lieu d'utiliser un gestionnaire de processus dans chaque conteneur qui démarre plusieurs processus de travail , ce que fait cette image Docker.
Dans ces cas (par exemple, à l'aide de Kubernetes), vous voudriez probablement créer une image Docker à partir de zéro , installer vos dépendances et exécuter un seul processus au lieu de cette image.
Par exemple, en utilisant Gunicorn, vous pourriez avoir une app/gunicorn_conf.py avec:
# Gunicorn config variables
loglevel = "info"
errorlog = "-" # stderr
accesslog = "-" # stdout
worker_tmp_dir = "/dev/shm"
graceful_timeout = 120
timeout = 120
keepalive = 5
threads = 3 Et puis vous pourriez avoir un Dockerfile avec:
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" ]Vous pouvez en savoir plus sur ces idées dans la documentation Fastapi sur: Fastapi dans les conteneurs - Docker comme les mêmes idées s'appliqueraient à d'autres applications Web dans des conteneurs.
Vous pouvez vouloir un gestionnaire de processus exécutant plusieurs processus de travail dans le conteneur si votre application est suffisamment simple pour que vous n'ayez pas besoin (du moins pas encore) pour affiner le nombre de processus trop, et vous pouvez simplement utiliser un défaut automatisé, et vous l'exécutez sur un seul serveur , pas un cluster.
Vous pouvez vous déployer sur un seul serveur (pas un cluster) avec Docker Compose , vous n'auriez donc pas de moyen facile de gérer la réplication des conteneurs (avec Docker Compose) tout en préservant le réseau partagé et l'équilibrage de charge .
Ensuite, vous pouvez avoir un seul conteneur avec un gestionnaire de processus commençant plusieurs processus de travail à l'intérieur, comme le fait cette image Docker.
Vous pourriez également avoir d'autres raisons qui faciliteraient le fait d'avoir un seul conteneur avec plusieurs processus au lieu d'avoir plusieurs conteneurs avec un seul processus dans chacun d'eux.
Par exemple (selon votre configuration), vous pouvez avoir un outil comme un exportateur de Prométhée dans le même conteneur qui devrait avoir accès à chacune des demandes qui arrivent.
Dans ce cas, si vous aviez plusieurs conteneurs , par défaut, lorsque Prometheus est venu lire les mesures , il obtiendrait ceux d' un seul conteneur à chaque fois (pour le conteneur qui a géré cette demande particulière), au lieu d'obtenir les métriques accumulées pour tous les conteneurs répliqués.
Ensuite, dans ce cas, il pourrait être plus simple d'avoir un conteneur avec plusieurs processus , et un outil local (par exemple un exportateur de Prométhée) sur le même conteneur collectant des mesures Prometheus pour tous les processus internes et exposant ces mesures sur ce seul conteneur.
En savoir plus sur tout cela dans la documentation Fastapi sur: Fastapi dans les conteneurs - Docker, car les mêmes concepts s'appliquent aux autres applications Web dans des conteneurs.
Vous n'avez pas à cloner ce dépôt.
Vous pouvez utiliser cette image comme image de base pour d'autres images.
En supposant que vous avez un fichier requirements.txt , vous pouvez avoir un Dockerfile comme celui-ci:
FROM tiangolo/uwsgi-nginx:python3.12
COPY ./requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY ./app /app
# Your Dockerfile code... Par défaut, il essaiera de trouver un fichier de configuration UWSGI dans /app/uwsgi.ini .
Que le fichier uwsgi.ini obligera à exécuter un fichier python dans /app/main.py .
Si vous créez une application Web Flask , vous devez utiliser à la place Tiangolo / UWSGI-nginx-flask .
Si vous avez besoin d'utiliser un répertoire pour votre application différente de /app , vous pouvez remplacer le chemin de fichier de configuration UWSGI avec une variable d'environnement UWSGI_INI et y mettre votre fichier uwsgi.ini personnalisé.
Par exemple, si vous aviez besoin d'avoir votre répertoire d'application dans /application au lieu de /app , votre Dockerfile ressemblerait:
FROM tiangolo/uwsgi-nginx:python3.12
ENV UWSGI_INI /application/uwsgi.ini
COPY ./application /application
WORKDIR /appapplication Et votre fichier uwsgi.ini dans ./application/uwsgi.ini contiendrait:
[uwsgi]
wsgi-file =/application/main.py Remarque : il est important d'inclure l'option WORKDIR , sinon UWSGI démarrera l'application dans /app .
Par défaut, l'image commence par 2 processus UWSGI en cours d'exécution. Lorsque le serveur connaît une charge élevée, il crée jusqu'à 16 processus UWSGI pour le gérer à la demande.
Si vous devez configurer ces nombres, vous pouvez utiliser des variables d'environnement.
Le numéro de départ des processus UWSGI est contrôlé par la variable UWSGI_CHEAPER , par défaut définie sur 2 .
Le nombre maximum de processus UWSGI est contrôlé par la variable UWSGI_PROCESSES , par défaut définie sur 16 .
Sachez que UWSGI_CHEAPER doit être inférieur à UWSGI_PROCESSES .
Donc, si, par exemple, vous devez commencer avec 4 processus et passer à un maximum de 64, votre Dockerfile pourrait ressembler:
FROM tiangolo/uwsgi-nginx:python3.12
ENV UWSGI_CHEAPER 4
ENV UWSGI_PROCESSES 64
COPY ./app /appDans cette image, Nginx est configuré pour permettre des tailles de fichiers de téléchargement illimitées. Cela se fait parce que par défaut, un simple serveur Python permettrait à cela, donc c'est le comportement le plus simple à lequel un développeur s'attendrait.
Si vous devez restreindre la taille maximale de téléchargement dans nginx, vous pouvez ajouter une variable d'environnement NGINX_MAX_UPLOAD et attribuer une valeur correspondant à la configuration nginx standard client_max_body_size .
Par exemple, si vous vouliez définir la taille maximale du fichier de téléchargement sur 1 Mo (la valeur par défaut dans une installation NGINX normale), vous devrez définir la variable d'environnement NGINX_MAX_UPLOAD sur la valeur 1m . Ensuite, l'image s'occuperait d'ajouter le fichier de configuration correspondant (ceci est fait par le entrypoint.sh ).
Donc, votre Dockerfile ressemblerait à quelque chose:
FROM tiangolo/uwsgi-nginx:python3.12
ENV NGINX_MAX_UPLOAD 1m
COPY ./app /appPar défaut, le conteneur fabriqué à partir de cette image écoutera sur le port 80.
Pour modifier ce comportement, définissez la variable d'environnement LISTEN_PORT .
Vous devrez peut-être également créer l'instruction EXPOSE Docker respective.
Vous pouvez le faire dans votre Dockerfile , cela ressemblerait à quelque chose:
FROM tiangolo/uwsgi-nginx:python3.12
ENV LISTEN_PORT 8080
EXPOSE 8080
COPY ./app /app/app/prestart.sh Si vous devez exécuter quelque chose avant de démarrer l'application, vous pouvez ajouter un fichier prestart.sh au répertoire /app . L'image détectera et l'exécutera automatiquement avant de tout démarrer.
Par exemple, si vous souhaitez ajouter des migrations de base de données qui sont exécutées sur le démarrage (par exemple avec Alembic ou Django Migrations), avant de démarrer l'application, vous pouvez créer un fichier ./app/prestart.sh dans votre répertoire de code (qui sera copié par votre Dockerfile ) avec:
#! /usr/bin/env bash
# Let the DB start
sleep 10 ;
# Run migrations
alembic upgrade head Et il attendrait 10 secondes pour donner à la base de données un peu de temps pour démarrer, puis exécuter cette commande alembic (vous pouvez mettre à jour cela pour exécuter les migrations Django ou tout autre outil dont vous avez besoin).
Si vous avez besoin d'exécuter un script Python avant de démarrer l'application, vous pouvez faire en sorte que le fichier /app/prestart.sh exécute votre script Python, avec quelque chose comme:
#! /usr/bin/env bash
# Run custom Python script before starting
python /app/my_custom_prestart_script.py Remarque : l'image utilise . Pour exécuter le script (comme dans . /app/prestart.sh ), donc par exemple, les variables d'environnement persisteraient. Si vous ne comprenez pas la phrase précédente, vous n'en avez probablement pas besoin.
Par défaut, Nginx commencera un "processus de travail".
Si vous souhaitez définir un autre nombre de processus de travail Nginx, vous pouvez utiliser la variable d'environnement NGINX_WORKER_PROCESSES .
Vous pouvez utiliser un numéro unique spécifique, par exemple:
ENV NGINX_WORKER_PROCESSES 2 Ou vous pouvez le définir sur le mot-clé auto et il essaiera de automatiquement le nombre de processeurs disponibles et de l'utiliser pour le nombre de travailleurs.
Par exemple, en utilisant auto , votre docker peut ressembler:
FROM tiangolo/uwsgi-nginx:python3.12
ENV NGINX_WORKER_PROCESSES auto
COPY ./app /appPar défaut, Nginx commencera par une limite maximale de 1024 connexions par travailleur.
Si vous souhaitez définir un numéro différent, vous pouvez utiliser la variable d'environnement NGINX_WORKER_CONNECTIONS , par exemple:
ENV NGINX_WORKER_CONNECTIONS 2048Il ne peut pas dépasser la limite actuelle du nombre maximum de fichiers ouverts. Voyez comment le configurer dans la section suivante.
Les connexions numériques par travailleur Nginx ne peuvent pas dépasser la limite du nombre maximum de fichiers ouverts.
Vous pouvez modifier la limite des fichiers ouverts avec la variable d'environnement NGINX_WORKER_OPEN_FILES , par exemple:
ENV NGINX_WORKER_OPEN_FILES 2048 Si vous avez besoin de configurer Nginx davantage, vous pouvez ajouter *.conf Files à /etc/nginx/conf.d/ dans votre Dockerfile .
Gardez simplement à l'esprit que les configurations par défaut sont créées lors du démarrage dans un fichier à /etc/nginx/conf.d/nginx.conf et /etc/nginx/conf.d/upload.conf . Vous ne devriez donc pas les écraser. Vous devez nommer votre fichier *.conf avec quelque chose de différent de nginx.conf ou upload.conf , par exemple: custom.conf .
Remarque : Si vous personnalisez Nginx, peut-être en copie des configurations à partir d'un blog ou d'une réponse StackOverflow, gardez à l'esprit que vous devez probablement utiliser les configurations spécifiques à UWSGI, au lieu de celles des autres modules, comme par exemple, ngx_http_fastcgi_module .
Si vous avez besoin de configurer Nginx encore plus loin, dépassant complètement les valeurs par défaut, vous pouvez ajouter une configuration Nginx personnalisée à /app/nginx.conf .
Il sera copié sur /etc/nginx/nginx.conf et utilisé à la place de celui généré.
Gardez à l'esprit que, dans ce cas, cette image ne générera aucune des configurations Nginx, elle ne copiera et n'utilisera que votre fichier de configuration.
Cela signifie que toutes les variables d'environnement décrites ci-dessus qui sont spécifiques à Nginx ne seront pas utilisées.
Cela signifie également qu'il n'utilisera pas de configurations supplémentaires à partir de fichiers dans /etc/nginx/conf.d/*.conf , sauf si vous avez explicitement une section dans votre fichier personnalisé /app/nginx.conf avec:
include /etc/nginx/conf.d/*.conf;
Si vous souhaitez ajouter un fichier personnalisé /app/nginx.conf mais ne savez pas par où commencer, vous pouvez utiliser le nginx.conf utilisé pour les tests et le personnaliser ou le modifier davantage.
La combinaison de UWSGI avec Nginx est un moyen courant de déployer des applications Web Python.
À peu près:
Nginx est un serveur Web, il s'occupe des connexions HTTP et peut également servir les fichiers statiques directement et plus efficacement.
UWSGI est un serveur d'applications, c'est ce qui exécute votre code Python et il parle avec Nginx.
Votre code Python a l'application Web réelle et est exécuté par UWSGI.
Cette image tire parti d'images Docker existantes déjà minces et optimisées (basées sur Debian comme recommandé par Docker) et implémente Docker les meilleures pratiques.
Il utilise l'image officielle Python Docker, installe UWSGI et en plus de cela, avec le moins de modifications, ajoute l'image Nginx officielle (à partir de 2016-02-14).
Et il contrôle tous ces processus avec SuperVisord.
Il y a la règle de base selon laquelle vous devriez avoir "un processus par conteneur".
Cela aide, par exemple, à isoler une application et sa base de données dans différents conteneurs.
Mais si vous voulez avoir une approche "micro-services", vous voudrez peut-être avoir plus d'un processus dans un conteneur s'ils sont tous liés au même "service", et vous voudrez peut-être inclure votre code FLASK, UWSGI et NGINX dans le même conteneur (et peut-être exécuter un autre conteneur avec votre base de données).
C'est l'approche adoptée dans cette image.
Cette image a un exemple par défaut "Hello World" dans le répertoire Container /app à l'aide de l'exemple dans la documentation UWSGI.
Vous souhaitez probablement le remplacer ou le supprimer dans votre projet.
Il est là au cas où vous exécuterez cette image par elle-même et non comme une image de base pour votre propre Dockerfile , afin que vous obteniez un exemple d'application sans erreurs.
En bref: vous ne devriez probablement pas utiliser Alpine pour les projets Python, utilisez plutôt les versions slim Docker Image.
Voulez-vous plus de détails? Continuer la lecture?
Alpine est plus utile pour d'autres langues où vous construisez un binaire statique dans une étape d'image Docker (en utilisant le bâtiment Docker en plusieurs étapes), puis le copiez sur une simple image alpine, puis exécutez simplement ce binaire. Par exemple, en utilisant Go.
Mais pour Python, car Alpine n'utilise pas l'outillage standard utilisé pour construire des extensions de Python, lors de l'installation de packages, dans de nombreux cas, Python ( pip ) ne trouvera pas un package installable précompilé (une "roue") pour Alpine. Et après le débogage de nombreuses erreurs étranges, vous vous rendrez compte que vous devez installer beaucoup d'outils supplémentaires et créer beaucoup de dépendances juste pour utiliser certains de ces packages Python courants. ?
Cela signifie que, bien que l'image alpine d'origine ait pu être petite, vous vous retrouvez avec une image avec une taille comparable à la taille que vous auriez obtenue si vous veniez d'utiliser une image python standard (basée sur Debian), ou dans certains cas encore plus grande. ?
Et dans tous ces cas, il faudra beaucoup plus de temps pour construire, consommer beaucoup plus de ressources, construire des dépendances plus longtemps et augmenter son empreinte carbone, car vous utilisez plus de temps et d'énergie CPU pour chaque construction. ?
Si vous voulez des images Slim Python, vous devriez plutôt essayer d'utiliser les versions slim qui sont toujours basées sur Debian, mais qui sont plus petites. ?
Toutes les balises d'image, les configurations, les variables d'environnement et les options d'application sont testées.
Les mises à jour sont annoncées dans les versions.
Vous pouvez cliquer sur le bouton "Regarder" en haut à droite et sélectionner "Release Only" pour recevoir une notification par e-mail lorsqu'il y a une nouvelle version.
*.pyc avec PYTHONDONTWRITEBYTECODE=1 et assurez-vous que les journaux sont imprimés immédiatement avec PYTHONUNBUFFERED=1 . PR # 208 par @ Estebanx64. EXPOSE pas les ports 80 et 443 par défaut car ils peuvent être personnalisés. PR # 227 par @tiangolo. issue-manager.yml . PR # 226 par @tiangolo.latest-changes . PR # 214 par @tiangolo.latest-changes.yml . PR # 201 par @alejsdev.README.md . PR # 199 par @alejsdev. Faits saillants de cette version:
python3.6-2022-11-25 et python2.7-2022-11-25 .2.0.20 . PR # 127 par @tiangolo.1.17.10 , basée sur la dernière debian, Buster. PR # 82.2020-05-04 .2019-10-14:
2019-09-28:
tiangolo/uwsgi-nginx:python3.7-2019-09-28 . PR # 65.Mettre à niveau Travis. PR # 60.
/app/prestart.sh pour exécuter du code arbitraire avant de démarrer l'application (par exemple, Alembic - Migrations Sqlalchemy). La documentation de /app/prestart.sh est dans la lecture principale. PR # 59.2019-05-04:
2019-02-02:
/app/nginx.conf qui remplace celui généré. PR # 51.2018-11-23: Nouvelles images Alpine 3.8 pour Python 2.7, Python 3.6 et Python 3.7 (Python 3.7 temporairement désactivé). Merci à Philippfreyer dans PR # 45
2018-09-22: Nouvelles versions Python 3.7, standard et alpin. Merci à DesaintMartin dans ce PR.
2018-06-22: Vous pouvez désormais utiliser NGINX_WORKER_CONNECTIONS pour définir le nombre maximum de connexions de travail Nginx et NGINX_WORKER_OPEN_FILES pour définir le nombre maximal de fichiers ouverts. Merci à Ronlut dans ce PR.
2018-06-22: Faites en sorte que UWSGI nécessite une application pour s'exécuter, au lieu de passer en "mode dynamique complet" pendant qu'il y avait une erreur. SuperVisord ne se termine pas mais essaie de redémarrer UWSGI et affiche les erreurs. Utilise need-app comme suggéré par Luckydonald dans ce commentaire.
2018-06-22: Arrêt gracieux correctement géré UWSGI et Nginx. Merci à DesaintMartin dans ce PR.
2018-02-04: Il est désormais possible de définir le nombre de processus de travail Nginx avec la variable d'environnement NGINX_WORKER_PROCESSES . Merci à Naktinis dans ce PR.
2018-01-14: Il existe maintenant deux versions basées sur Alpine, python2.7-alpine3.7 et python3.6-alpine3.7 .
2017-12-08: Vous pouvez maintenant configurer le port sur lequel le conteneur doit écouter, en utilisant la variable d'environnement LISTEN_PORT grâce à TMSHN dans ce PR.
2017-08-09: Vous pouvez définir une taille de fichier de téléchargement maximale personnalisée à l'aide d'une variable d'environnement NGINX_MAX_UPLOAD , par défaut, il a une valeur de 0 , qui permet des tailles de fichiers de téléchargement illimitées. Cela diffère de la valeur par défaut de Nginx de 1 Mo. Il est configuré de cette façon parce que c'est l'expérience la plus simple qu'un développeur qui n'est pas expert dans Nginx s'attendrait.
2017-08-09: Maintenant, vous pouvez remplacer où chercher le fichier uwsgi.ini , et avec cela, modifiez le répertoire par défaut de /app sur autre chose, en utilisant la variable Envirnoment UWSGI_INI .
2017-08-08: Il y a une nouvelle image latest étiquette, juste pour afficher un avertissement pour ceux qui utilisent toujours latest applications Web Python 2.7. À ce jour, tout le monde devrait utiliser Python 3.
2017-08-08: Supervisord termine maintenant UWSGI sur SIGTERM , donc si vous exécutez docker stop ou quelque chose de similaire, cela arrêtera en fait tout, au lieu d'attendre le délai d'expiration de Docker pour tuer le conteneur.
2017-07-31: Il y a maintenant une balise d'image pour Python 3.6, basée sur l'image officielle de Python 3.6 grâce à JRD dans ce PR.
2016-10-01: Vous pouvez désormais remplacer les paramètres uwsgi.ini par défaut à partir du fichier dans /app/uwsgi.ini .
2016-08-16: Il y a maintenant une balise d'image pour Python 3.5, basée sur l'image officielle de Python 3.5. Alors maintenant, vous pouvez utiliser cette image pour vos projets dans Python 2.7 et Python 3.5.
2016-08-16: Utilisez dynamique un certain nombre de processus de travail pour UWSGI, de 2 à 16 selon la charge. Cela devrait fonctionner pour la plupart des cas. Cela aide surtout lorsqu'il y a des réponses qui sont lentes et qui prennent un certain temps pour être généré, ce changement permet à toutes les autres réponses de rester rapidement (dans un nouveau processus) sans avoir à attendre la première (lente) la finition.
En outre, il utilise désormais un fichier uwsgi.ini de base sous /etc/uwsgi/ avec la plupart des configurations générales, donc, le uwsgi.ini à l'intérieur /app (celui que vous pourriez avoir besoin pour modifier) est désormais beaucoup plus simple.
2016-04-05: les journaux Nginx et UWSGI sont désormais redirigés vers STDOUT, permettant d'utiliser docker logs .
Ce projet est concédé sous licence de la licence Apache.