Wie man Flask-Anwendungen mit Gunicorn und Nginx unter Ubuntu 22.04 bereitstellt

A previous version of this tutorial was written by Kathleen Juell.

Einführung

In diesem Leitfaden werden Sie eine Python-Anwendung unter Verwendung des Flask-Microframeworks auf Ubuntu 22.04 erstellen. Der Großteil dieses Tutorials wird sich damit befassen, wie Sie den Gunicorn-Anwendungsserver einrichten und wie Sie die Anwendung starten und Nginx konfigurieren können, um als Front-End-Reversproxy zu fungieren.

Voraussetzungen

Bevor Sie diesen Leitfaden beginnen, sollten Sie folgendes haben:

  • Einen Server mit Ubuntu 22.04 installiert und einem Nicht-Root-Benutzer mit Sudo-Berechtigungen. Befolgen Sie unsere Anleitung zur ersten Servereinrichtung.

  • Nginx installiert, indem Sie Schritte 1 und 2 von So installieren Sie Nginx auf Ubuntu 22.04 befolgen.

  • Ein Domainname, der so konfiguriert ist, dass er auf Ihren Server zeigt. Sie können einen auf Namecheap kaufen oder einen kostenlos auf Freenom erhalten. Wie Sie Domains auf DigitalOcean zeigen können, erfahren Sie in der entsprechenden Dokumentation zu Domains und DNS. Stellen Sie sicher, die folgenden DNS-Einträge zu erstellen:

    • Einen A-Eintrag mit deine_domain, der auf die öffentliche IP-Adresse Ihres Servers zeigt.
    • Einen A-Eintrag mit www.deine_domain, der auf die öffentliche IP-Adresse Ihres Servers zeigt.
  • Vertrautheit mit der WSGI-Spezifikation, die der Gunicorn-Server verwenden wird, um mit Ihrer Flask-Anwendung zu kommunizieren. Diese Diskussion behandelt WSGI ausführlicher.

Schritt 1 — Installation der Komponenten aus den Ubuntu-Repositories

Der erste Schritt besteht darin, alle erforderlichen Komponenten aus den Ubuntu-Repositories zu installieren. Dazu gehört pip, der Python-Paketmanager, der die Python-Komponenten verwalten wird. Sie erhalten auch die Python-Entwicklungsdateien, die erforderlich sind, um einige der Gunicorn-Komponenten zu erstellen.

Zuerst aktualisieren Sie den lokalen Paketindex und installieren die Pakete, die es Ihnen ermöglichen, Ihre Python-Umgebung zu erstellen. Dazu gehören python3-pip sowie einige weitere Pakete und Entwicklungstools, die für eine robuste Programmierumgebung erforderlich sind:

  1. sudo apt update
  2. sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

Mit diesen Paketen bereitgestellt, ist der nächste Schritt die Erstellung einer virtuellen Umgebung für Ihr Projekt.

Schritt 2 — Erstellen einer Python-Virtual-Umgebung

Als nächstes richten Sie eine virtuelle Umgebung ein, um die Flask-Anwendung von den anderen Python-Dateien auf Ihrem System zu isolieren.

Beginnen Sie mit der Installation des Pakets python3-venv, das das Modul venv installiert:

  1. sudo apt install python3-venv

Als nächstes erstellen Sie ein übergeordnetes Verzeichnis für Ihr Flask-Projekt. Wechseln Sie nach dessen Erstellung mit dem cd-Befehl in das Verzeichnis:

  1. mkdir ~/myproject
  2. cd ~/myproject

Erstellen Sie eine virtuelle Umgebung, um die Python-Anforderungen Ihres Flask-Projekts zu speichern, indem Sie Folgendes eingeben:

  1. python3 -m venv myprojectenv

Dies installiert eine lokale Kopie von Python und pip in einem Verzeichnis namens myprojectenv innerhalb Ihres Projektverzeichnisses.

Bevor Sie Anwendungen innerhalb der virtuellen Umgebung installieren, müssen Sie sie aktivieren. Dies geschieht durch Eingabe von:

  1. source myprojectenv/bin/activate

Ihr Prompt ändert sich, um anzuzeigen, dass Sie jetzt innerhalb der virtuellen Umgebung arbeiten. Es wird ungefähr so aussehen: (myprojectenv)user@host:~/myproject$.

Schritt 3 — Einrichten einer Flask-Anwendung

Jetzt, da Sie sich in Ihrer virtuellen Umgebung befinden, können Sie Flask und Gunicorn installieren und mit dem Entwurf Ihrer Anwendung beginnen.

Zuerst installieren Sie wheel mit der lokalen Instanz von pip, um sicherzustellen, dass Ihre Pakete auch installiert werden, wenn die Wheel-Archive fehlen:

  1. pip install wheel

Hinweis

Unabhängig von der verwendeten Python-Version sollten Sie, wenn die virtuelle Umgebung aktiviert ist, den Befehl pip verwenden (nicht pip3).

Anschließend installieren Sie Flask und Gunicorn:

  1. pip install gunicorn flask

Erstellen einer Beispiel-App

Jetzt, da Sie Flask zur Verfügung haben, können Sie eine einfache Anwendung erstellen. Flask ist ein Mikroframework. Es enthält nicht viele der Werkzeuge, die umfangreichere Frameworks möglicherweise enthalten, und besteht hauptsächlich als Modul, das Sie in Ihre Projekte importieren können, um Ihnen bei der Initialisierung einer Webanwendung zu helfen.

Auch wenn Ihre Anwendung komplexer sein könnte, werden wir unsere Flask-App in einer einzigen Datei namens myproject.py erstellen:

  1. nano ~/myproject/myproject.py

Der Anwendungscode wird in dieser Datei leben. Es wird Flask importieren und ein Flask-Objekt instanziieren. Sie können dies verwenden, um die Funktionen zu definieren, die ausgeführt werden sollen, wenn eine bestimmte Route angefordert wird:

~/myproject/myproject.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "<h1 style='color:blue'>Hello There!</h1>"

if __name__ == "__main__":
    app.run(host='0.0.0.0')

Dies definiert im Grunde genommen, welcher Inhalt präsentiert werden soll, wenn die Root-Domäne aufgerufen wird. Speichern und schließen Sie die Datei, wenn Sie fertig sind.

Wenn Sie der Anleitung zur initialen Servereinrichtung gefolgt sind, sollte eine UFW-Firewall aktiviert sein. Um die Anwendung zu testen, müssen Sie den Zugriff auf den Port 5000 erlauben:

  1. sudo ufw allow 5000

Jetzt können Sie Ihre Flask-App testen, indem Sie Folgendes eingeben:

  1. python myproject.py

Sie sehen eine Ausgabe ähnlich der folgenden, einschließlich einer hilfreichen Warnung, die Sie daran erinnert, diese Servereinrichtung nicht in der Produktion zu verwenden:

Output
* Serving Flask app "myproject" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

Besuchen Sie die IP-Adresse Ihres Servers gefolgt von :5000 in Ihrem Webbrowser:

http://your_server_ip:5000

Sie sollten etwas Ähnliches sehen wie:

Wenn Sie fertig sind, drücken Sie Strg-C in Ihrem Terminalfenster, um den Flask-Entwicklungsserver zu stoppen.

Erstellen des WSGI-Einstiegspunkts

Als nächstes erstellen Sie eine Datei, die als Einstiegspunkt für Ihre Anwendung dient. Dadurch wird dem Gunicorn-Server mitgeteilt, wie er mit der Anwendung interagieren soll.

Nennen Sie die Datei wsgi.py:

  1. nano ~/myproject/wsgi.py

In dieser Datei importieren Sie die Flask-Instanz aus unserer Anwendung und führen sie dann aus:

~/myproject/wsgi.py
from myproject import app

if __name__ == "__main__":
    app.run()

Speichern und schließen Sie die Datei, wenn Sie fertig sind.

Schritt 4 – Konfiguration von Gunicorn

Ihre Anwendung ist nun mit einem Einstiegspunkt erstellt. Sie können nun damit fortfahren, Gunicorn zu konfigurieren.

Bevor Sie fortfahren, überprüfen Sie, ob Gunicorn die Anwendung korrekt bedienen kann.

Dies können Sie tun, indem Sie ihm den Namen des Einstiegspunkts der Anwendung übergeben. Dieser wird aus dem Namen des Moduls (ohne die Erweiterung .py) und dem Namen des Aufrufbaren innerhalb der Anwendung konstruiert. In diesem Fall ist es wsgi:app.

Geben Sie außerdem die Schnittstelle und den Port an, an die gebunden werden soll, indem Sie das Argument 0.0.0.0:5000 verwenden, damit die Anwendung auf einer öffentlich verfügbaren Schnittstelle gestartet wird:

  1. cd ~/myproject
  2. gunicorn --bind 0.0.0.0:5000 wsgi:app

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Output
[2020-05-20 14:13:00 +0000] [46419] [INFO] Starting gunicorn 20.0.4 [2020-05-20 14:13:00 +0000] [46419] [INFO] Listening at: http://0.0.0.0:5000 (46419) [2020-05-20 14:13:00 +0000] [46419] [INFO] Using worker: sync [2020-05-20 14:13:00 +0000] [46421] [INFO] Booting worker with pid: 46421

Besuchen Sie erneut die IP-Adresse Ihres Servers in Ihrem Webbrowser, gefolgt von :5000:

http://your_server_ip:5000

Sie sollten die Ausgabe Ihrer Anwendung sehen:

Wenn Sie bestätigt haben, dass sie ordnungsgemäß funktioniert, drücken Sie STRG-C in Ihrem Terminalfenster.

Wenn Sie mit der Verwendung der virtuellen Umgebung fertig sind, können Sie sie deaktivieren:

  1. deactivate

Alle Python-Befehle werden nun wieder die Python-Umgebung des Systems verwenden.

Als nächstes erstellen Sie die systemd-Service-Unit-Datei. Durch Erstellen einer systemd-Unit-Datei kann das Init-System von Ubuntu Gunicorn automatisch starten und die Flask-Anwendung immer dann bereitstellen, wenn der Server hochfährt.

Erstellen Sie eine Unit-Datei mit der Endung .service im Verzeichnis /etc/systemd/system:

  1. sudo nano /etc/systemd/system/myproject.service

Darin beginnen Sie mit dem Abschnitt [Unit], der zur Angabe von Metadaten und Abhängigkeiten verwendet wird. Fügen Sie hier eine Beschreibung Ihres Dienstes hinzu und teilen Sie dem Init-System mit, dass dieser erst gestartet werden soll, nachdem das Netzwerkziel erreicht wurde:

/etc/systemd/system/myproject.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

Fügen Sie als Nächstes einen Abschnitt [Service] hinzu. Hiermit legen Sie den Benutzer und die Gruppe fest, unter denen der Prozess ausgeführt werden soll. Geben Sie Ihrem regulären Benutzerkonto die Besitzrechte am Prozess, da es alle relevanten Dateien besitzt. Geben Sie außerdem der Gruppe www-data die Besitzrechte, damit Nginx problemlos mit den Gunicorn-Prozessen kommunizieren kann. Denken Sie daran, den Benutzernamen hier durch Ihren eigenen zu ersetzen:

/etc/systemd/system/myproject.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

[Service]
User=sammy
Group=www-data

Als nächstes müssen Sie das Arbeitsverzeichnis zuordnen und die Umgebungsvariable PATH so setzen, dass das Init-System weiß, dass die ausführbaren Dateien für den Prozess innerhalb unserer virtuellen Umgebung liegen. Geben Sie auch den Befehl zum Starten des Dienstes an. Dieser Befehl wird folgendes tun:

  • Starten Sie 3 Worker-Prozesse (passen Sie dies bei Bedarf an)
  • Erstellen und binden Sie eine Unix-Socket-Datei, myproject.sock, innerhalb unseres Projektverzeichnisses. Wir setzen einen Umask-Wert von 007, damit die Socket-Datei erstellt wird und Zugriff für den Besitzer und die Gruppe gewährt wird, während anderer Zugriff eingeschränkt wird
  • Geben Sie den Dateinamen des WSGI-Einstiegspunkts sowie den Python-Aufruf in dieser Datei an (wsgi:app)

Systemd erfordert, dass Sie den vollständigen Pfad zur Gunicorn-Ausführbaren angeben, die in Ihrer virtuellen Umgebung installiert ist.

Vergessen Sie nicht, den Benutzernamen und die Projekt-Pfade durch Ihre eigenen Informationen zu ersetzen:

/etc/systemd/system/myproject.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app

Zuletzt fügen Sie eine [Install]-Sektion hinzu. Dies teilt systemd mit, was dieser Dienst verknüpfen soll, wenn Sie ihn aktivieren, um beim Booten zu starten. Sie möchten, dass dieser Dienst gestartet wird, wenn das reguläre Mehrbenutzer-System hochgefahren ist:

/etc/systemd/system/myproject.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app

[Install]
WantedBy=multi-user.target

Mit diesen Schritten ist Ihre systemd-Service-Datei vollständig. Speichern und schließen Sie sie jetzt.

Sie können nun den von Ihnen erstellten Gunicorn-Dienst starten und aktivieren, damit er beim Booten gestartet wird:

  1. sudo systemctl start myproject
  2. sudo systemctl enable myproject

Überprüfen wir den Status:

  1. sudo systemctl status myproject

Sie sollten eine Ausgabe wie diese sehen:

Output
● myproject.service - Gunicorn instance to serve myproject Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2022-05-10 19:40:41 UTC; 9s ago Main PID: 17300 (gunicorn) Tasks: 4 (limit: 2327) Memory: 56.0M CPU: 514ms CGroup: /system.slice/myproject.service ├─17300 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─17301 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─17302 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app └─17303 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app May 10 19:40:41 r systemd[1]: Started Gunicorn instance to serve myproject. . . .

Wenn Sie Fehler sehen, stellen Sie sicher, dass Sie diese vor der Fortsetzung des Tutorials beheben.

Schritt 5 — Konfigurieren von Nginx zum Weiterleiten von Anfragen

Ihr Gunicorn-Anwendungsserver sollte jetzt ausgeführt und darauf warten, Anfragen auf der Socket-Datei im Projektverzeichnis entgegenzunehmen. Jetzt können Sie Nginx konfigurieren, um Webanfragen an diese Socket weiterzuleiten, indem Sie einige kleine Ergänzungen zu seiner Konfigurationsdatei vornehmen.

Beginnen Sie damit, eine neue Serverblock-Konfigurationsdatei im sites-available-Verzeichnis von Nginx zu erstellen. Nennen Sie dies meinprojekt, um sich an den Rest des Leitfadens zu halten:

  1. sudo nano /etc/nginx/sites-available/myproject

Öffnen Sie einen Serverblock und teilen Sie Nginx mit, auf dem Standardport 80 zu hören. Teilen Sie ihm auch mit, diesen Block für Anfragen nach dem Domainnamen unseres Servers zu verwenden:

/etc/nginx/sites-available/myproject
server {
    listen 80;
    server_name your_domain www.your_domain;
}

Fügen Sie als nächstes einen Ortsblock hinzu, der jede Anfrage abgleicht. Innerhalb dieses Blocks fügen Sie die Datei proxy_params ein, die einige allgemeine Proxy-Parameter spezifiziert, die gesetzt werden müssen. Leiten Sie dann die Anfragen an die von Ihnen definierte Socket mit der proxy_pass-Direktive weiter:

/etc/nginx/sites-available/myproject
server {
    listen 80;
    server_name your_domain www.your_domain;

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
    }
}

Speichern und schließen Sie die Datei, wenn Sie fertig sind.

Um die Nginx-Serverblockkonfiguration zu aktivieren, die Sie gerade erstellt haben, verlinken Sie die Datei mit dem sites-enabled-Verzeichnis:

  1. sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

Mit der Datei in diesem Verzeichnis können Sie auf Syntaxfehler testen:

  1. sudo nginx -t

Wenn dies ohne Anzeige von Problemen zurückkehrt, starten Sie den Nginx-Prozess neu, um die neue Konfiguration zu lesen:

  1. sudo systemctl restart nginx

Schließlich passen Sie die Firewall erneut an. Sie benötigen keinen Zugriff mehr über den Port 5000, daher können Sie diese Regel entfernen. Sie können dann den vollständigen Zugriff auf den Nginx-Server erlauben:

  1. sudo ufw delete allow 5000
  2. sudo ufw allow 'Nginx Full'

Sie sollten nun in der Lage sein, die Domain Ihres Servers in Ihrem Webbrowser aufzurufen:

http://your_domain

Sie sollten die Ausgabe Ihrer Anwendung sehen:

Hinweis: Sie erhalten einen HTTP 502 Gateway-Fehler, wenn Nginx nicht auf die Socket-Datei von Gunicorn zugreifen kann. Normalerweise liegt das daran, dass das Heimatverzeichnis des Benutzers anderen Benutzern den Zugriff auf darin befindliche Dateien nicht erlaubt.

Wenn Ihre Socket-Datei /home/sammy/myproject/myproject.sock heißt, stellen Sie sicher, dass /home/sammy mindestens Berechtigungen von 0755 hat. Sie können ein Tool wie chmod verwenden, um die Berechtigungen wie folgt zu ändern:

  1. sudo chmod 755 /home/sammy

Laden Sie dann die Seite neu, um zu sehen, ob der HTTP 502 Fehler verschwindet.

Wenn Sie auf Fehler stoßen, versuchen Sie Folgendes zu überprüfen:

  • sudo less /var/log/nginx/error.log: überprüft die Nginx-Fehlerprotokolle.
  • sudo less /var/log/nginx/access.log: überprüft die Nginx-Zugriffsprotokolle.
  • sudo journalctl -u nginx: überprüft die Nginx-Prozessprotokolle.
  • sudo journalctl -u myproject: überprüft die Gunicorn-Protokolle Ihrer Flask-App.

Schritt 6 — Sichern der Anwendung

Um sicherzustellen, dass der Datenverkehr zu Ihrem Server sicher bleibt, lassen Sie uns ein SSL-Zertifikat für Ihre Domain erhalten. Es gibt mehrere Möglichkeiten, dies zu tun, einschließlich des Erhalts eines kostenlosen Zertifikats von Let’s Encrypt, des Generierens eines selbstsignierten Zertifikats oder des Kaufens eines Zertifikats von einem anderen Anbieter und Konfigurieren von Nginx, um es gemäß den Schritten 2 bis 6 von Wie man ein selbstsigniertes SSL-Zertifikat für Nginx in Ubuntu 22.04 erstellt zu verwenden. Wir werden die Option eins (Let’s Encrypt) der Einfachheit halber nutzen.

Installieren Sie das Nginx-Paket von Certbots mit apt:

  1. sudo apt install python3-certbot-nginx

Certbot bietet verschiedene Möglichkeiten, SSL-Zertifikate über Plugins zu erhalten. Das Nginx-Plugin kümmert sich um die Neukonfiguration von Nginx und lädt die Konfiguration bei Bedarf neu. Verwenden Sie dieses Plugin, geben Sie folgendes ein:

  1. sudo certbot --nginx -d your_domain -d www.your_domain

Dies führt certbot mit dem --nginx-Plugin aus und verwendet -d, um die Namen anzugeben, für die das Zertifikat gültig sein soll.

Wenn dies das erste Mal ist, dass Sie certbot ausführen, werden Sie aufgefordert, eine E-Mail-Adresse einzugeben und den Nutzungsbedingungen zuzustimmen. Nachdem Sie dies getan haben, wird certbot mit dem Let’s Encrypt-Server kommunizieren und dann eine Herausforderung durchführen, um zu überprüfen, dass Sie die Domain kontrollieren, für die Sie ein Zertifikat beantragen.

Wenn das erfolgreich ist, wird certbot Sie fragen, wie Sie Ihre HTTPS-Einstellungen konfigurieren möchten:

Output
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. ------------------------------------------------------------------------------- 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

Wählen Sie Ihre Wahl aus und drücken Sie dann die Eingabetaste (ENTER). Die Konfiguration wird aktualisiert, und Nginx wird neu geladen, um die neuen Einstellungen zu übernehmen. certbot wird mit einer Nachricht abschließen, die Ihnen mitteilt, dass der Vorgang erfolgreich war und wo Ihre Zertifikate gespeichert sind:

Output
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/your_domain/privkey.pem Your cert will expire on 2020-08-18. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

Wenn Sie den Nginx-Installationsanweisungen in den Voraussetzungen gefolgt sind, benötigen Sie die redundante HTTP-Profilzulassung nicht mehr:

  1. sudo ufw delete allow 'Nginx HTTP'

Zur Überprüfung der Konfiguration navigieren Sie erneut zu Ihrer Domain, diesmal mit https://:

https://your_domain

Sie sollten erneut Ihre Anwendungsausgabe sehen, zusammen mit dem Sicherheitsindikator Ihres Browsers, der anzeigen sollte, dass die Website gesichert ist.

Abschluss

In diesem Leitfaden haben Sie eine einfache Flask-Anwendung innerhalb einer Python-Virtualumgebung erstellt und abgesichert. Sie haben einen WSGI-Einstiegspunkt erstellt, damit jeder WSGI-fähige Anwendungsserver damit kommunizieren kann, und dann den Gunicorn-App-Server konfiguriert, um diese Funktion bereitzustellen. Anschließend haben Sie eine systemd-Service-Datei erstellt, um den Anwendungsserver beim Booten automatisch zu starten. Sie haben auch einen Nginx-Serverblock erstellt, der den Webclient-Verkehr an den Anwendungsserver weiterleitet, externe Anfragen übermittelt und den Verkehr zu Ihrem Server mit Let’s Encrypt abgesichert.

Flask ist ein sehr einfaches, aber äußerst flexibles Framework, das dazu gedacht ist, Ihren Anwendungen Funktionalität zu bieten, ohne dabei zu restriktiv in Bezug auf Struktur und Design zu sein. Sie können den allgemeinen Stack, der in diesem Leitfaden beschrieben wird, verwenden, um die von Ihnen entworfenen Flask-Anwendungen zu bedienen.

Source:
https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-22-04