Dockerfile -Linkspython3.12 , latest (Dockerfile)python3.11 , (Dockerfile)python3.10 (Dockerfile)python3.9 , (Dockerfile) Diese Tags werden nicht mehr unterstützt oder aufrechterhalten, sie werden aus dem Github -Repository entfernt, aber die letzten Versionen sind möglicherweise noch in Docker Hub verfügbar, wenn jemand sie gezogen hat:
python3.8python3.8-alpinepython3.7python3.6python2.7Die letzten Datum -Tags für diese Versionen sind:
python3.8-2024-10-28python3.8-alpine-2024-03-11python3.7-2024-10-28python3.6-2022-11-25python2.7-2022-11-25 Hinweis : Es gibt Tags für jedes Build -Datum. Wenn Sie die von Ihnen verwendete Docker -Bildversion "Pin" "pin" müssen, können Sie eines dieser Tags auswählen. tiangolo/uwsgi-nginx-flask:python3.7-2019-10-14
Docker -Bild mit UWSGI und NGINX für Flask -Webanwendungen in Python , das in einem einzigen Container ausgeführt wird.
Mit diesem Docker -Bild können Sie Flask -Webanwendungen in Python erstellen, die mit UWSGI und NGINX in einem einzigen Container ausgeführt werden.
Die Kombination von UWSGI mit NGINX ist eine häufige Möglichkeit, Webanwendungen von Python Flask bereitzustellen.
Wenn Sie ein neues Projekt starten, möchten Sie vielleicht Fastapi ausprobieren, das ich erstellt habe und wo ich die meiste Zeit verbringe. Es benötigt auch kein benutzerdefiniertes Basisbild. Es gibt Anweisungen in den Dokumenten, um Ihre eigene Dockerfile zu erstellen.
Github Repo : https://github.com/tiangolo/uwsgi-nginx-flask-docker
Docker Hub Image : https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/
Sie verwenden wahrscheinlich Kubernetes oder ähnliche Tools. In diesem Fall benötigen Sie dieses Bild (oder ein anderes ähnliches Basisbild ) wahrscheinlich nicht . Sie sind wahrscheinlich besser dran, ein Docker -Bild von Grund auf neu zu erstellen .
Wenn Sie über eine Gruppe von Maschinen mit Kubernetes , Docker Swarm -Modus, NOMAD oder einem ähnlichen komplexen System verfügen, um verteilte Container auf mehreren Maschinen zu verwalten, möchten Sie wahrscheinlich die Replikation auf Clusterebene verarbeiten, anstatt einen Prozessmanager in jedem Container zu verwenden, der mehrere Arbeiterprozesse startet, was dieses Docker -Bild ist.
In diesen Fällen (z. B. mit Kubernetes) möchten Sie wahrscheinlich ein Docker -Bild von Grund auf neu erstellen, Ihre Abhängigkeiten installieren und einen einzelnen Prozess anstelle dieses Bildes ausführen.
Mit Gunicorn können Sie beispielsweise eine Datei app/gunicorn_conf.py mit:
# Gunicorn config variables
loglevel = "info"
errorlog = "-" # stderr
accesslog = "-" # stdout
worker_tmp_dir = "/dev/shm"
graceful_timeout = 120
timeout = 120
keepalive = 5
threads = 3 Und dann könnten Sie eine Dockerfile haben mit:
FROM python:3.12
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" ]Weitere Informationen zu diesen Ideen finden Sie in der Fastapi -Dokumentation zu: Fastapi in Containern - Docker wie die gleichen Ideen würden für andere Webanwendungen in Containern gelten.
Sie möchten, dass ein Prozessmanager mehrere Arbeiterprozesse im Container ausführt, wenn Ihre Anwendung einfach genug ist, dass Sie (zumindest noch nicht) die Anzahl der Prozesse zu stark abschneiden, und Sie können nur einen automatisierten Standard verwenden, und Sie führen ihn auf einem einzelnen Server aus, nicht auf einem Cluster.
Sie könnten mit Docker Compose auf einem einzelnen Server (kein Cluster) bereitgestellt werden, sodass Sie keine einfache Möglichkeit haben, die Replikation von Containern (mit Docker Compose) zu verwalten, während Sie das gemeinsame Netzwerk und das Lastausgleich erhalten haben.
Dann möchten Sie einen einzelnen Container mit einem Prozessmanager, der mehrere Arbeitsprozesse startet, wie dieses Docker -Image.
Sie können auch andere Gründe haben, die es einfacher machen würden, einen einzelnen Container mit mehreren Prozessen zu haben, anstatt mehrere Container mit einem einzelnen Prozess in jedem von ihnen zu haben.
Zum Beispiel (abhängig von Ihrem Setup) können Sie ein Tool wie einen Prometheus -Exporteur im selben Container haben, der Zugriff auf jede der kommenden Anforderungen haben sollte.
In diesem Fall, wenn Sie standardmäßig mehrere Container hätten, wenn Prometheus die Metriken las , würde jedes Mal die für einen einzelnen Container (für den Container, der diese bestimmte Anfrage bearbeitet), anstatt die akkumulierten Metriken für alle replizierten Container zu erhalten.
In diesem Fall könnte es dann einfacher sein, einen Container mit mehreren Prozessen und ein lokales Tool (z. B. ein Prometheus -Exporteur) auf demselben Container zu sammeln, das Prometheus -Metriken für alle internen Prozesse sammelt und diese Metriken auf diesem einzelnen Container freigibt.
Lesen Sie mehr darüber in der Fastapi -Dokumentation über: Fastapi in Containern - Docker, wie dieselben Konzepte für andere Webanwendungen in Containern gelten.
Sie müssen dieses Repo nicht klonen.
Sie können dieses Bild als Basisbild für andere Bilder verwenden.
Angenommen, Sie haben Dockerfile requirements.txt .
FROM tiangolo/uwsgi-nginx-flask:python3.12
COPY ./requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY ./app /appEs sind mehrere Bild -Tags verfügbar, aber für neue Projekte sollten Sie die neueste verfügbare Version verwenden.
Dieses Docker-Bild basiert auf Tiangolo/UWSGI-Nginx . Dieses Docker -Bild hat UWSGI und Nginx im selben Container installiert und wurde als Grundlage dieses Bildes gemacht.
Dockerfile mit: FROM tiangolo/uwsgi-nginx-flask:python3.12
COPY ./app /appapp -Verzeichnis und geben Sie es einmain.py -Datei (sie sollte so genannt werden und in Ihrem app -Verzeichnis sein) mit: from flask import Flask
app = Flask ( __name__ )
@ app . route ( "/" )
def hello ():
return "Hello World from Flask"
if __name__ == "__main__" :
# Only for debugging while developing
app . run ( host = '0.0.0.0' , debug = True , port = 80 ) Das Hauptanwendungsobjekt sollte als app (im Code) als in diesem Beispiel bezeichnet werden.
Hinweis : Der Abschnitt mit der Funktion main() dient zu Debugging -Zwecken. Um mehr zu erfahren, lesen Sie die fortgeschrittenen Anweisungen unten.
.
├── app
│ └── main.py
└── Dockerfile
Dockerfile Ihr app -Verzeichnis enthält)docker build -t myimage .docker run -d --name mycontainer -p 80:80 myimage... und Sie haben einen optimierten Flask -Server in einem Docker -Container.
Sie sollten es in der URL Ihres Docker -Containers überprüfen können, z. B. http://192.168.99.100 oder http://127.0.0.1
Wenn Sie moderne Frontend -Anwendungen (z. B. VUE, React, Angular) erstellen, würden Sie höchstwahrscheinlich eine moderne Version von JavaScript (ES2015, Typecript usw.) in eine weniger modernere, kompatiblere Version zusammenstellen.
Wenn Sie Ihren (kompilierten) Frontend -Code durch denselben Backend -Docker -Container servieren möchten, müssten Sie den Code nach dem Kompilieren in den Container kopieren.
Das bedeutet, dass Sie alle Frontend -Tools auf der Gebäudemaschine installieren müssen (es kann Ihr Computer, ein Remote -Server usw. sind).
Das bedeutet auch, dass Sie immer daran denken müssten, den Frontend -Code kurz vor dem Erstellen des Docker -Bildes zu kompilieren.
Und es kann auch bedeuten, dass Sie Ihren kompilierten Frontend -Code zu Ihrem git -Repository hinzufügen müssen (hoffentlich verwenden Sie Git bereits oder lernen, wie Sie git verwenden).
Das Hinzufügen Ihres kompilierten Code zu Git ist aus mehreren Gründen eine sehr schlechte Idee, einige davon sind:
Aus diesen Gründen wird nicht empfohlen, Ihren Frontend -Code aus dem Docker -Container desselben Backends (Flasks) zu servieren.
Es gibt eine viel bessere Alternative, um Ihren Frontend -Code aus demselben Backend -Docker -Container (Flask) zu servieren.
Sie können einen weiteren Docker -Container mit allen Frontend -Tools (Node.js usw.) haben, die:
Um die Einzelheiten dieses Prozesses für das Frontend -Gebäude in Docker zu erfahren, können Sie lesen:
Nach einem Backend -Behälter (Flask) und einem Frontend -Behälter müssen Sie beide servieren.
Und Sie möchten sie vielleicht unter derselben Domäne unter einem anderen Weg dienen. Zum Beispiel die Backend (Flask) App am Pfad /api und am Frontend am "Root" -Path / .
Sie können dann Traefik verwenden, um damit umzugehen.
Außerdem kann es automatisch HTTPS -Zertifikate für Ihre Anwendung mit LECS Encrypt generieren. Alles kostenlos, in einem sehr einfachen Setup.
Wenn Sie diese Alternative verwenden möchten, überprüfen Sie die obigen Projektgeneratoren, sie verwenden alle diese Idee.
In diesem Szenario hätten Sie 3 Docker -Container:
Sie sollten in der Lage sein, dieselben Anweisungen wie im obigen Abschnitt " QuickStart " mit einigen geringfügigen Änderungen zu befolgen:
app/ das Verzeichnis einzulegen, geben Sie ihn in eine Verzeichnis app/app/ ein.__init__.py in dieses app/app/ -verzeichnis hinzu.uwsgi.ini in Ihr app/ /app/uwsgi.ini Verzeichnis hinzu (das in den Container kopiert wird).uwsgi.ini -Datei hinzu: [uwsgi]
module = app.main
callable = app Die Erklärung des uwsgi.ini lautet wie folgt:
app.main . In der Paket app ( /app/app ) erhalten Sie also das main ( main.py ).app -Objekt ( app = Flask(__name__) ).Ihre Dateistruktur würde aussehen wie:
.
├── app
│ ├── app
│ │ ├── __init__.py
│ │ ├── main.py
│ └── uwsgi.ini
└── Dockerfile
...anstatt:
.
├── app
│ ├── main.py
└── Dockerfile
Wenn Sie statische Dateien im selben Container verwenden, stellen Sie sicher, dass die Umgebungsvariable STATIC_PATH entsprechend festgelegt wird. Zum Beispiel, um den Standardwert /app/static zu /app/app/static zu ändern, können Sie diese Zeile zu Ihrer Dockerfile hinzufügen:
ENV STATIC_PATH /app/app/static... Danach sollte alles wie erwartet funktionieren. Alle anderen Anweisungen würden normal gelten.
.
├── app
│ ├── app
│ │ ├── api
│ │ │ ├── api.py
│ │ │ ├── endpoints
│ │ │ │ ├── __init__.py
│ │ │ │ └── user.py
│ │ │ ├── __init__.py
│ │ │ └── utils.py
│ │ ├── core
│ │ │ ├── app_setup.py
│ │ │ ├── database.py
│ │ │ └── __init__.py
│ │ ├── __init__.py
│ │ ├── main.py
│ │ └── models
│ │ ├── __init__.py
│ │ └── user.py
│ └── uwsgi.ini
└── Dockerfile
Stellen Sie sicher, dass Sie den offiziellen Dokumenten befolgen, während Sie Ihre Module importieren:
Wenn Sie beispielsweise in app/app/main.py sind und das Modul in app/app/core/app_setup.py importieren möchten, würden Sie es schreiben wie:
from . core import app_setupoder
from app . core import app_setupapp/app/api/endpoints/user.py sind und das users aus app/app/core/database.py importieren möchten, würden Sie es schreiben, wie: from ... core . database import usersoder
from app . core . database import users Sie können verschiedene Dinge mit Umgebungsvariablen anpassen.
index.html direktHinweis : Diese Technik ist veraltet, da sie mehrere Probleme mit modernen Frontend -Frameworks verursachen kann. Für die Details und bessere Alternativen lesen Sie den obigen Abschnitt.
Festlegen der Umgebungsvariablen STATIC_INDEX auf 1 Sie können nginx so konfigurieren, dass die Datei in der URL /static/index.html bereitgestellt wird, wenn sie für / angefordert werden.
Das würde die Geschwindigkeit verbessern, da es weder UWSGI noch Python beinhalten würde. Nginx würde die Datei direkt bedienen. Weitere Informationen finden Sie im obigen Abschnitt " QuickStart for Spas ".
Um dies zu aktivieren, können Sie dies zu Ihrer Dockerfile hinzufügen:
ENV STATIC_INDEX 1Standardmäßig beginnt das Bild mit 2 UWSGI -Prozessen. Wenn der Server eine hohe Last hat, werden bis zu 16 UWSGI -Prozesse erstellt, um sie bei Bedarf zu bewältigen.
Wenn Sie diese Zahlen konfigurieren müssen, können Sie Umgebungsvariablen verwenden.
Die Startnummer der UWSGI -Prozesse wird standardmäßig von der variablen UWSGI_CHEAPER auf 2 gesteuert.
Die maximale Anzahl von UWSGI -Prozessen wird standardmäßig durch die variable UWSGI_PROCESSES auf 16 gesteuert.
Denken Sie daran, dass UWSGI_CHEAPER niedriger sein muss als UWSGI_PROCESSES .
Wenn Sie beispielsweise mit 4 Prozessen beginnen und maximal 64 wachsen müssen, könnte Ihre Dockerfile wie:
FROM tiangolo/uwsgi-nginx-flask:python3.12
ENV UWSGI_CHEAPER 4
ENV UWSGI_PROCESSES 64
COPY ./app /app Sie können eine benutzerdefinierte maximale Upload -Dateigröße mit einer Umgebungsvariablen NGINX_MAX_UPLOAD festlegen, die standardmäßig einen Wert von 0 hat, der unbegrenzte Upload -Dateigrößen ermöglicht. Dies unterscheidet sich vom Standardwert von Nginx von 1 MB. Es ist auf diese Weise konfiguriert, da dies die einfachste Erfahrung ist, die ein unerfahrener Entwickler in Nginx erwarten würde.
Wenn Sie beispielsweise eine maximale Hochladungsdateigröße von 1 MB (NGINX -Standard) haben, fügen Sie eine Zeile in Ihrem Dockerfile hinzu mit:
ENV NGINX_MAX_UPLOAD 1mStandardmäßig hört der Container aus diesem Bild auf Port 80 an.
Um dieses Verhalten zu ändern, legen Sie die Umgebungsvariable LISTEN_PORT fest. Möglicherweise müssen Sie auch den EXPOSE Docker -Anweisungen erstellen.
Sie können das in Ihrer Dockerfile tun, es würde ungefähr so aussehen wie:
FROM tiangolo/uwsgi-nginx-flask:python3.12
ENV LISTEN_PORT 8080
EXPOSE 8080
COPY ./app /appuwsgi.ini -Konfigurationen Es gibt eine Standarddatei in /app/uwsgi.ini mit App -spezifischen Konfigurationen (zusätzlich zu den globalen uwsgi -Konfigurationen).
Es enthält nur:
[uwsgi]
module = main
callable = appmodule = main bezieht sich auf die Datei main.pycallable = app bezieht sich auf die Flask "Anwendung" in der Variablen app . Sie können uwsgi anpassen, indem Sie diese Datei durch Ihre eigenen ersetzen, einschließlich aller Ihrer Konfigurationen.
Um beispielsweise die obigen Standard -Threads zu erweitern und Threads zu aktivieren, können Sie eine Datei haben:
[uwsgi]
module = main
callable = app
enable-threads = trueuwsgi.ini Dateispeicherort Sie können überschreiben, wo das Bild nach der App uwsgi.ini -Datei mit der Umgebungsvariablen UWSGI_INI suchen soll.
Damit können Sie das Standardverzeichnis für Ihre App von /app in etwas anderes wie /application ändern.
Damit das Bild die Datei in /application/uwsgi.ini verwendet, können Sie dies zu Ihrer Dockerfile hinzufügen:
ENV UWSGI_INI /application/uwsgi.ini
COPY ./application /application
WORKDIR /application Hinweis : Der WORKDIR ist wichtig, ansonsten wird UWSGI versuchen, die App in /app auszuführen.
Hinweis : Sie müssten auch den Pfad der static Dateien konfigurieren, lesen Sie unten.
./static/ Pfad Sie können Nginx damit ein benutzerdefiniertes Verzeichnispfad mit den Dateien verwenden, um direkt mit der Umgebungsvariablen STATIC_PATH (ohne UWSGI beteiligt zu haben).
Um beispielsweise Nginx den statischen Inhalt mit den Dateien in /app/custom_static/ zu dienen, können Sie diese zu Ihrer Dockerfile hinzufügen:
ENV STATIC_PATH /app/custom_static Wenn der Browser dann nach einer Datei in http://example.com/static/index.html fragte, antwortete Nginx direkt mit einer Datei im Path /app/custom_static/index.html index.html.
HINWEIS : Sie müssten auch Flask konfigurieren, um dies als static Verzeichnis zu verwenden.
Wenn Sie Ihren Anwendungscode in einem anderen Verzeichnis einfügen mussten, können Sie NGINX so konfigurieren, dass diese statischen Dateien aus diesem verschiedenen Verzeichnis bereitgestellt werden.
Wenn Sie Ihre statischen Dateien in /application/static/ Sie benötigen, können Sie dies zu Ihrer Dockerfile hinzufügen:
ENV STATIC_PATH /application/static/static URL Sie können auch dazu führen, dass Nginx die statischen Dateien in einer anderen URL diente. Dafür können Sie die Umgebungsvariable STATIC_URL verwenden.
Wenn Sie beispielsweise die URL /static in /content ändern möchten, können Sie dies zu Ihrer Dockerfile hinzufügen:
ENV STATIC_URL /content Wenn der Browser dann nach einer Datei in http://example.com/content/index.html fragte, antwortete Nginx direkt mit einer Datei in den Path /app/static/index.html .
/app/prestart.sh Wenn Sie vor dem Starten der App etwas ausführen müssen, können Sie dem Verzeichnis /app eine Datei prestart.sh hinzufügen. Das Bild erkennt und führt es automatisch aus, bevor Sie alles starten.
Wenn Sie beispielsweise alembische SQL -Migrationen (mit SQLAlchemy) hinzufügen möchten, können Sie in Ihrem Code Dockerfile eine ./app/prestart.sh .
#! /usr/bin/env bash
# Let the DB start
sleep 10 ;
# Run migrations
alembic upgrade head Und es würde 10 Sekunden warten, um der Datenbank einige Zeit zum Starten zu geben und diesen alembic Befehl auszuführen.
Wenn Sie vor dem Starten der App ein Python -Skript ausführen müssen, können Sie die Datei /app/prestart.sh Ihr Python -Skript mit so etwas wie folgt ausführen:
#! /usr/bin/env bash
# Run custom Python script before starting
python /app/my_custom_prestart_script.py HINWEIS : Das Bild verwendet source , um das Skript auszuführen, sodass die Umgebungsvariablen beispielsweise bestehen bleiben würden. Wenn Sie den vorherigen Satz nicht verstehen, brauchen Sie ihn wahrscheinlich nicht.
Standardmäßig startet Nginx einen "Arbeiterprozess".
Wenn Sie eine andere Anzahl von Nginx -Worker -Prozessen festlegen möchten, können Sie die Umgebungsvariable NGINX_WORKER_PROCESSES verwenden.
Sie können eine bestimmte Einzelnummer verwenden, z. B.:
ENV NGINX_WORKER_PROCESSES 2 Oder Sie können es auf das Keyword- auto einstellen und es wird versuchen, die Anzahl der verfügbaren CPUs automatisch zu erkennen und diese für die Anzahl der Arbeitnehmer zu verwenden.
Zum Beispiel könnte Ihre Dockerfile mit automatischer Weise wie bei der Verwendung von auto aussehen:
FROM tiangolo/uwsgi-nginx-flask:python3.12
ENV NGINX_WORKER_PROCESSES auto
COPY ./app /appStandardmäßig beginnt Nginx mit einer maximalen Grenze von 1024 Verbindungen pro Arbeiter.
Wenn Sie eine andere Nummer festlegen möchten, können Sie die Umgebungsvariable NGINX_WORKER_CONNECTIONS verwenden, z. B.:
ENV NGINX_WORKER_CONNECTIONS 2048Es kann die aktuelle Grenze für die maximale Anzahl geöffneter Dateien nicht überschreiten. Sehen Sie, wie Sie es im nächsten Abschnitt konfigurieren.
Die Zahlenverbindungen pro NGINX -Arbeiter können die Grenze für die maximale Anzahl geöffneter Dateien nicht überschreiten.
Sie können die Grenze von geöffneten Dateien mit der Umgebungsvariablen NGINX_WORKER_OPEN_FILES ändern, z. B.:
ENV NGINX_WORKER_OPEN_FILES 2048 Wenn Sie Nginx weiter konfigurieren müssen, können Sie in Ihrem Dockerfile *.conf -Dateien zu /etc/nginx/conf.d/ hinzufügen.
Denken Sie nur daran, dass die Standardkonfigurationen während des Starts in einer Datei unter /etc/nginx/conf.d/nginx.conf und /etc/nginx/conf.d/upload.conf erstellt werden. Sie sollten sie also nicht überschreiben. Sie sollten Ihre *.conf -Datei mit etwas anderem als nginx.conf oder upload.conf benennen, z. B. custom.conf .
Hinweis : Wenn Sie Nginx anpassen, können Sie möglicherweise Konfigurationen aus einem Blog oder einer Stackoverflow -Antwort kopieren, denken Sie daran, dass Sie wahrscheinlich die für UWSGI spezifischen Konfigurationen verwenden müssen, anstatt diejenigen für andere Module, wie zum Beispiel ngx_http_fastcgi_module .
Wenn Sie Nginx noch weiter konfigurieren müssen und die Standardeinstellungen vollständig überschreiben müssen, können Sie eine benutzerdefinierte Nginx -Konfiguration zu /app/nginx.conf hinzufügen.
Es wird in /etc/nginx/nginx.conf kopiert und anstelle des erzeugten verwendet.
Beachten Sie, dass dieses Bild in diesem Fall keine der Nginx -Konfigurationen generiert, sondern Ihre Konfigurationsdatei nur kopiert und verwendet.
Dies bedeutet, dass alle oben beschriebenen Umgebungsvariablen, die spezifisch für Nginx sind, nicht verwendet werden.
Dies bedeutet auch, dass keine zusätzlichen Konfigurationen von Dateien in /etc/nginx/conf.d/*.conf verwendet werden, es sei denn, Sie haben explizit einen Abschnitt in Ihrem benutzerdefinierten Datei /app/nginx.conf mit:
include /etc/nginx/conf.d/*.conf;
Wenn Sie eine benutzerdefinierte Datei /app/nginx.conf hinzufügen möchten, aber nicht wissen, wohin Sie beginnen sollen, können Sie die für die Tests verwendete nginx.conf verwenden und anpassen oder weiter ändern.
Die Kombination von UWSGI mit NGINX ist eine häufige Möglichkeit, Webanwendungen von Python Flask bereitzustellen.
Rund:
Nginx ist ein Webserver, er kümmert sich um die HTTP -Verbindungen und kann auch statische Dateien direkt und effizienter bereitstellen.
UWSGI ist ein Anwendungsserver, das führt Ihren Python -Code aus und spricht mit Nginx.
Ihr Python -Code verfügt über die tatsächliche Flask -Webanwendung und wird von UWSGI ausgeführt.
Das Image Tiangolo/UWSGI-Nginx nutzt bereits vorhandene schlanke und optimierte Docker-Bilder (basierend auf Debian, wie von Docker empfohlen) und implementiert einige der Best Practices von Docker.
Es verwendet das offizielle Python Docker -Bild, installiert UWSGI und fügt das offizielle Nginx -Bild hinzu (mit der geringsten Menge an Änderungen).
Und es kontrolliert all diese Prozesse mit Supervisford.
Das von diesem Repo erstellte Bild (und Tags) basiert auf dem Bild Tiangolo/uwsgi-nginx . Dieses Bild fügt einen Flask und vernünftige Standardeinstellungen hinzu.
Wenn Sie den Anweisungen befolgen und das Root -Verzeichnis /app in Ihrem Container aufbewahren, mit einer Datei namens main.py und einem Flask -Objekt mit dem Namen app IT sollte es "einfach funktionieren".
Es gibt bereits eine uwsgi.ini -Datei im Verzeichnis /app mit den UWSGI -Konfigurationen, damit sie "nur arbeiten". Und alle anderen erforderlichen Parameter befinden sich in einer anderen uwsgi.ini -Datei im Bild in /etc/uwsgi/ .
Wenn Sie den Hauptdateinamen oder das Hauptflaschenobjekt ändern müssen, müssten Sie Ihre eigene uwsgi.ini -Datei angeben. Sie können das in diesem Repo zunächst als Vorlage verwenden (und Sie müssten nur die 2 entsprechenden Zeilen ändern).
Sie können ein /app/static Verzeichnis haben und diese Dateien werden von NGINX direkt (ohne Ihren Flask -Code oder sogar Ihren UWSGI) effizient bedient, das ist bereits für Sie konfiguriert. Sie können es jedoch mithilfe von Umgebungsvariablen (oben gelesen) weiter konfigurieren.
Supervisford kümmert sich um das Ausführen von UWSGI mit der Datei uwsgi.ini in /app (einschließlich auch der Datei in /etc/uwsgi/uwsgi.ini ) und Start von nginx.
Es gibt die Faustregel, dass Sie "einen Prozess pro Container" haben sollten.
Dies hilft beispielsweise, eine App und ihre Datenbank in verschiedenen Containern zu isolieren.
Wenn Sie jedoch einen "Micro-Services" -Ansatz haben möchten, möchten Sie möglicherweise mehr als einen Prozess in einem Container haben, wenn sie alle mit demselben "Service" zusammenhängen, und Sie möchten möglicherweise Ihren Flask-Code, UWSGI und NGINX in denselben Container (und führen Sie möglicherweise einen anderen Container mit Ihrer Datenbank aus).
Das ist der Ansatz in diesem Bild.
Dieses Bild (und Tags) verfügt über einige Standarddateien. Wenn Sie es also selbst ausführen (nicht als Grundbild Ihres eigenen Projekts), sehen Sie eine Standard -Web -App "Hello World".
Wenn Sie eine Dockerfile mit einer COPY ./app /app ersetzen Sie diese Standarddateien durch Ihren App -Code.
Die Hauptdatei ist nur in /app/main.py . Und im Fall der Tags mit -index , auch in /app/static/index.html .
Diese Dateien rendern jedoch einen Text "(Standard)" auf der servierten Webseite, damit Sie überprüfen können, ob Sie den Standardcode oder Ihren eigenen Code sehen, der die Standardeinstellung überschreitet.
Ihr App -Code sollte sich im Verzeichnis des Containers /app befinden. Es sollte eine main.py -Datei haben und diese main.py -Datei sollte eine Flask -Objekt app haben.
Wenn Sie den obigen Anweisungen befolgen oder eines der herunterladbaren Beispielvorlagen verwenden, sollten Sie in Ordnung sein.
In den Bildern befindet sich auch eine a /app/uwsgi.ini -Datei mit den Standardparametern für UWSGI.
Die herunterladbaren Beispiele enthalten eine Kopie derselben uwsgi.ini -Datei für Debugging -Zwecke. Um mehr zu erfahren, lesen Sie die folgenden " fortgeschrittenen Entwicklungsanweisungen ".
Während der Entwicklung möchten Sie Ihr Codeverzeichnis möglicherweise zu einem Volumen in Ihrem Docker -Container machen.
Damit würden Sie Ihre Dateien jedes Mal aktualisieren, wenn Sie sie ändern, ohne Ihren Container erneut zu erstellen.
Dazu können Sie den Befehl pwd (Print Working Directory) in Ihrem docker run und das Flag -v für Volumes verwenden.
Damit können Sie Ihr Verzeichnis ./app dem Verzeichnis Ihres Containers /app zuordnen.
Als Sie das Verzeichnis /app in Ihrem Container (und alle seine Inhalte) vollständig ersetzen, müssen Sie jedoch eine uwsgi.ini -Datei in Ihrem Verzeichnis ./app mit:
[uwsgi]
module = main
callable = appUnd dann können Sie die Docker -Volumenzuordnung durchführen.
Hinweis : Eine uwsgi.ini -Datei ist in den herunterladbaren Beispielen enthalten.
Dockerfile und Ihrem ./app -Verzeichnis)uwsgi.ini -Datei in Ihrem ./app -Verzeichnis habendocker build -t myimage ../app ) auf das Verzeichnis Ihres Containers /app zuordnen: docker run -d --name mycontainer -p 80:80 -v $( pwd ) /app:/app myimage Wenn Sie zu Ihrer URL Ihrer Docker -Container gehen, sollten Sie Ihre App sehen und in der Lage sein, Dateien in ./app/static/ zu ändern und diese Änderungen in Ihrem Browser nur durch Nachladen zu sehen.
... Aber wenn UWSGI Ihre gesamte Python -Flask -Webanwendung lädt, wenn sie beginnt, können Sie Ihren Python -Flask -Code nicht bearbeiten und die Änderungen sehen.
Um (vorübergehend) Ihren Python -Flask -Code live (vorübergehend) zu debuggen, können Sie Ihren Container -Befehl ausführen (der SupervisOrd startet, der wiederum UWSGI und NGINX startet) und Ihre Anwendung direkt mit python im Debug -Modus im Debug -Modus ausführen, indem Sie den Befehl flask mit seinen Umgebungsvariablen verwenden.
Bei all den oben genannten Änderungen und der direkten Ausführung Ihrer App mit flask wäre der endgültige Docker -Befehl:
docker run -d --name mycontainer -p 80:80 -v $( pwd ) /app:/app -e FLASK_APP=main.py -e FLASK_DEBUG=1 myimage flask run --host=0.0.0.0 --port=80 Oder im Fall eines Paketprojekts würden Sie FLASK_APP=main/main.py festlegen:
docker run -d --name mycontainer -p 80:80 -v $( pwd ) /app:/app -e FLASK_APP=main/main.py -e FLASK_DEBUG=1 myimage flask run --host=0.0.0.0 --port=80Jetzt können Sie Ihren Flask -Code in Ihrem lokalen Computer bearbeiten. Sobald Sie Ihren Browser aktualisiert haben, werden die Änderungen live angezeigt.
Denken Sie daran, dass Sie dies nur für das Debuggen und die Entwicklung verwenden sollten. Für die Bereitstellung in der Produktion sollten Sie keine Volumes montieren, und Sie sollten Supervisford starten lassen und es uwsgi und nginx starten lassen (was standardmäßig passiert).
Eine Alternative für diese letzten Schritte zur Arbeit, wenn Sie kein Paket haben, sondern nur eine flache Struktur mit einzelnen Dateien (Modulen). Ihr Python -Flask -Code könnte diesen Abschnitt mit:
if __name__ == "__main__" :
# Only for debugging while developing
app . run ( host = '0.0.0.0' , debug = True , port = 80 ) ... und du könntest es mit python main.py laufen lassen. Das funktioniert jedoch nur, wenn Sie keine Paketstruktur verwenden und nicht planen, dies später zu tun. Wenn Sie den obigen Codeblock nicht hinzugefügt haben, hört Ihre App nur localhost (im Container), in einem anderen Port (5000) und nicht im Debug -Modus an.
Wenn Sie das gleiche Live / mit /app/static/index.html STATIC_INDEX=1 durchführen möchten.
from flask import Flask , send_fileUnd
@ app . route ( '/' )
def route_root ():
index_path = os . path . join ( app . static_folder , 'index.html' )
return send_file ( index_path ) ... Das stellt sicher, dass Ihre App auch die Datei /app/static/index.html dient, wenn sie für / angefordert werden. Oder wenn Sie eine Paketstruktur verwenden, die Datei /app/main/static/index.html .
Und wenn Sie ein SPA -Framework verwenden, um die URLs im Browser zu verarbeiten, sollte Ihr Python -Flask -Code den Abschnitt mit:
# Everything not declared before (not a Flask route / API endpoint)...
@ app . route ( '/<path:path>' )
def route_frontend ( path ):
# ...could be a static file needed by the front end that
# doesn't use the `static` path (like in `<script src="bundle.js">`)
file_path = os . path . join ( app . static_folder , path )
if os . path . isfile ( file_path ):
return send_file ( file_path )
# ...or should be handled by the SPA's "router" in front end
else :
index_path = os . path . join ( app . static_folder , 'index.html' )
return send_file ( index_path ) ... Dadurch sendet Flask alle CSS-, JavaScript- und Bilddateien, wenn sie in der Root ( / ) -URL angefordert werden, stellt jedoch auch sicher, dass Ihr Frontend -Spa alle anderen URLs behandelt, die nicht in Ihrer Flask -App definiert sind.
So ist es im obigen Tutorial geschrieben und ist in den herunterladbaren Beispielen enthalten.
Wenn Sie den obigen Anweisungen befolgen, ist es wahrscheinlich, dass Sie irgendwann Code schreiben, der Ihren Flask -Debugging -Server durchbricht, und es stürzt ab.
Und da der einzige Prozess, der ausgeführt wurde, Ihr Debugging -Server war, der jetzt gestoppt wird, wird Ihr Container gestoppt.
Dann müssen Sie Ihren Container nach dem Fixieren Ihres Codes erneut starten und nicht ganz einfach sehen, was der Fehler ist, der Ihren Server abstürzt.
Während der Entwicklung können Sie Folgendes tun (das ist es, was ich normalerweise mache, obwohl ich es mit Docker komponiere, wie in den Beispielprojekten):
docker run -d --name mycontainer -p 80:80 -v $( pwd ) /app:/app -e FLASK_APP=main.py -e FLASK_DEBUG=1 myimage bash -c " while true ; do sleep 10 ; done "FLASK_APP=main/main.py : docker run -d --name mycontainer -p 80:80 -v $( pwd ) /app:/app -e FLASK_APP=main/main.py -e FLASK_DEBUG=1 myimage bash -c " while true ; do sleep 10 ; done "docker exec -it mycontainer bash Sie werden jetzt in Ihrem Container im Verzeichnis /app sein.
flask run --host=0.0.0.0 --port=80Sie werden sehen, wie Ihr Flask-Debugging-Server beginnt, Sie sehen, wie die Antworten an jede Anfrage gesendet werden, die Fehler, die beim Aufbrechen Ihres Codes geworfen werden, und wie sie Ihren Server anhalten, und Sie können ihn sehr schnell neu starten, indem Sie den Befehl oben erneut ausführen.
Alle Bild -Tags, Konfigurationen, Umgebungsvariablen und Anwendungsoptionen werden getestet.
issue-manager.yml . PR #385 von @tiangolo.latest-changes GitHub-Aktionen. PR #360 von @tiangolo.latest-changes.yml . PR #348 von @alejsdev.README.md . PR #346 von @alejsdev. Highlights dieser Veröffentlichung:
python3.6-2022-11-25 und python2.7-2022-11-25 .1.17.10 .3.11 .-index sufix tags.-index (use ENV STATIC_INDEX 1 instead).2020-05-04 .tiangolo/uwsgi-nginx-flask:python3.8-2019-10-14 . PR #154./start.sh and /app/prestart.sh functionality to parent image. PR #134.2019-02-02:
uwsgi-nginx and PR #121./app/nginx.conf file that overrides the generated one. PR #51 in the parent image uwsgi-nginx and PR #122.2019-01-01:
2018-12-29:
2018-11-23:
2018-09-22:
2018-06-22:
NGINX_WORKER_CONNECTIONS to set the maximum number of Nginx worker connections and NGINX_WORKER_OPEN_FILES to set the maximum number of open files. Thanks to ronlut in this PR.2018-06-22:
Improvements from parent image:
Make uWSGI require an app to run, instead of going in "full dynamic mode" while there was an error. Supervisord doesn't terminate itself but tries to restart uWSGI and shows the errors. Uses need-app as suggested by luckydonald in this comment.
Correctly handled graceful shutdown of uWSGI and Nginx. Thanks to desaintmartin in this PR.
2018-02-04:
It's now possible to set the number of Nginx worker processes with the environment variable NGINX_WORKER_PROCESSES . Thanks to naktinis in this PR.
2018-01-14:
python2.7-alpine3.7 and python3.6-alpine3.7 .2017-12-10:
/app/prestart.sh script to run arbitrary code before starting the app (for example, Alembic - SQLAlchemy migrations). The documentation for the /app/prestart.sh is in the main README./app is part of the PYTHONPATH environment variable. That allows global imports from several places, easier Alembic integration, etc. 2017-12-08: Now you can configure which port the container should listen on, using the environment variable LISTEN_PORT thanks to tmshn in this PR.
2017-09-10: Updated examples and sample project to work with SPAs even when structuring the app as a package (with subdirectories).
2017-09-02:
flask run commands, that allows running a package application while developing more easily.2017-08-10: Many changes:
python3.6 , python3.6-index , python.3.5 , python3.5-index , python2.7 and python2.7-index . All the other images are deprecated in favor is this ones.latest will point to Python 3.6 and the other tags will be removed.tiangolo/uwsgi-nginx that improved this image too.index.html directly: STATIC_INDEXNGINX_MAX_UPLOADuwsgi.ini file (that allows using a custom directory different than /app ): UWSGI_INI (using the ideas by @bercikr in #5 )../static/ path: STATIC_PATH/static/ URL: STATIC_URLDockerfile with: FROM tiangolo/uwsgi-nginx-flask:python3.6
COPY ./app /appand then customize with environment variables.
This project is licensed under the terms of the Apache license.