Wie man eine Flask-Anwendung mit uWSGI und Nginx auf Ubuntu 20.04 einsetzt

Flask ist ein in Python geschriebenes Mikro-Webframework, das von Armin Ronacher entwickelt wurde. Es wird Mikroframework genannt, weil es keine Tools oder Bibliotheken benötigt. Flask ist ein Python-Modul und hat einen kleinen und einfach zu erweiternden Kern, mit dem du leicht Webanwendungen entwickeln kannst.

In diesem Tutorium lernen wir, wie man eine Flask-Anwendung mit Uwsgi und Nginx auf Ubuntu 20.04 einsetzt.

Voraussetzungen

  • Ein Server, auf dem Ubuntu 20.04 läuft.
  • Ein gültiger Domainname, der auf die IP deines Servers zeigt.
  • Der Server ist mit einem Root-Passwort konfiguriert.

Erste Schritte

Zuerst solltest du deine Systempakete auf die neueste Version aktualisieren. Du kannst sie aktualisieren, indem du den folgenden Befehl ausführst:

apt-get update -y

Sobald alle Pakete aktualisiert sind, kannst du mit dem nächsten Schritt fortfahren.

Erforderliche Abhängigkeiten installieren

Als Nächstes musst du einige Abhängigkeiten installieren, die für die Bereitstellung der Flask-Anwendung erforderlich sind. Du kannst sie alle mit dem folgenden Befehl installieren:

apt-get install nginx python3-pip python3-dev python3-venv build-essential libssl-dev libffi-dev python3-setuptools -y

Sobald alle Pakete installiert sind, kannst du mit dem nächsten Schritt fortfahren.

Eine virtuelle Umgebung erstellen

Als Nächstes musst du eine virtuelle Umgebung für deine Flask-Anwendung erstellen. Die virtuelle Umgebung ist ein sehr nützliches Werkzeug, um isolierte Python-Umgebungen zu erstellen. Sie hilft dir, eine bestimmte Version von Python für dein Projekt zu installieren.

Erstelle zunächst mit dem folgenden Befehl ein Verzeichnis für deine Flask-Anwendung:

mkdir /var/www/html/myapp

Als Nächstes änderst du das Verzeichnis in myapp und erstellst mit dem folgenden Befehl eine neue virtuelle Python-Umgebung:

cd /var/www/html/myapp
python3.8 -m venv myappenv

Als Nächstes aktivierst du die virtuelle Umgebung mit dem folgenden Befehl:

source myappenv/bin/activate

Einrichten einer Flask-Anwendung

Jetzt ist die virtuelle Python-Umgebung bereit für den Einsatz der Flask-Anwendung. Als Nächstes musst du eine Flask-Anwendung in deiner virtuellen Umgebung einrichten.

Installiere zunächst Flask und uWSGI mit dem folgenden Befehl:

pip install uwsgi flask

Als Nächstes erstellst du eine Beispielanwendung namens myapp.py mit folgendem Befehl:

nano /var/www/html/myapp/myapp.py

Füge die folgenden Zeilen hinzu:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "<h1 style='color:blue'>Hi This is My Flask Application</h1>"

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

Speichere und schließe die Datei, wenn du fertig bist. Starte deine Flask-Anwendung mit dem folgenden Befehl:

python /var/www/html/myapp/myapp.py

Du solltest die folgende Ausgabe sehen:

 * Serving Flask app "myapp" (lazy loading)
 * Environment: production
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

Öffne nun deinen Webbrowser und rufe deine Flask-Anwendung über die URL http://your-server-ip:5000 auf . Du solltest den folgenden Bildschirm sehen:

Flask App

Drücke jetzt die Tastenkombination STRG + C in deinem Terminal, um die Flask-Anwendung zu beenden.

uWSGI konfigurieren

Erstelle zunächst einen WSGI-Einstiegspunkt, um deinem uWSGI-Server mitzuteilen, wie er mit dir interagieren soll.

nano /var/www/html/myapp/wsgi.py

Füge die folgenden Zeilen hinzu, um deine Flask-Instanz aus deiner Anwendung zu importieren:

from myapp import app

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

Speichere und schließe die Datei, wenn du fertig bist, und teste dann mit dem folgenden Befehl, ob uWSGI die Anwendung bedienen kann:

uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app

Rufe nun deine Anwendung erneut über die URL http://your-server-ip:5000 auf. Du solltest den folgenden Bildschirm sehen:

Zugriff auf die Flask-App unter Ubuntu

Drücke nun STRG + C, um die Anwendung zu beenden.

Führe anschließend den folgenden Befehl aus, um deine virtuelle Umgebung zu verlassen:

deactivate

uWSGI konfigurieren

Jetzt ist uWSGI in der Lage, deine Anwendung zu bedienen. Erstelle nun eine uWSGI-Konfigurationsdatei mit dem folgenden Befehl:

nano /var/www/html/myapp/myapp.ini

Füge die folgenden Zeilen hinzu:

[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = myapp.sock
chmod-socket = 660
vacuum = true

die-on-term = true

Speichere und schließe die Datei, wenn du fertig bist.

Eine Systemd-Dienstdatei erstellen

Als Nächstes musst du eine systemd-Dienstdatei erstellen, um den uWSGI-Dienst zu verwalten. Du kannst sie mit dem folgenden Befehl erstellen:

nano /etc/systemd/system/myapp.service

Füge die folgenden Zeilen ein:

[Unit]
Description=uWSGI instance to serve myapp
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/html/myapp
Environment="PATH=/var/www/html/myapp/myappenv/bin"
ExecStart=/var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini

[Install]
WantedBy=multi-user.target

Speichere und schließe die Datei, wenn du fertig bist, und lade den systemd-Daemon mit dem folgenden Befehl neu:

systemctl daemon-reload

Als Nächstes änderst du die Eigentümerschaft deiner Anwendung in www-data und gibst die entsprechenden Rechte mit dem folgenden Befehl ein:

chown -R www-data:www-data /var/www/html/myapp
chmod -R 775 /var/www/html/myapp

Starte deine Anwendung und aktiviere sie mit folgendem Befehl, damit sie beim Neustart des Systems gestartet wird:

systemctl start myapp
systemctl enable myapp

Du kannst den Status deiner Anwendung auch mit folgendem Befehl überprüfen:

systemctl status myapp

Du solltest die folgende Ausgabe erhalten:

? myapp.service - uWSGI instance to serve myapp
     Loaded: loaded (/etc/systemd/system/myapp.service; disabled; vendor preset: enabled)
     Active: active (running) since Sun 2020-09-13 08:38:08 UTC; 1min 53s ago
   Main PID: 662796 (uwsgi)
      Tasks: 6 (limit: 4691)
     Memory: 21.8M
     CGroup: /system.slice/myapp.service
             ??662796 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini
             ??662808 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini
             ??662809 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini
             ??662810 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini
             ??662811 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini
             ??662812 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini


Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x55e207e7a510 pid: 662796 (default app)
Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: *** uWSGI is running in multiple interpreter mode ***
Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI master process (pid: 662796)
Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI worker 1 (pid: 662808, cores: 1)
Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI worker 2 (pid: 662809, cores: 1)
Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI worker 3 (pid: 662810, cores: 1)
Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI worker 4 (pid: 662811, cores: 1)
Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI worker 5 (pid: 662812, cores: 1)

Nginx als Reverse Proxy konfigurieren

Als Nächstes musst du Nginx als Reverse Proxy konfigurieren, um die Flask-Anwendung zu bedienen. Das kannst du mit dem folgenden Befehl tun:

nano /etc/nginx/sites-available/flask.conf

Füge die folgenden Zeilen hinzu:

server {
    listen 80;
    server_name flask.example.com;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/var/www/html/myapp/myapp.sock;
    }
}

Speichere und schließe die Datei, wenn du fertig bist. Als Nächstes überprüfst du Nginx mit folgendem Befehl auf einen Syntaxfehler:

nginx -t

Du solltest die folgende Ausgabe sehen:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Als Nächstes aktivierst du den virtuellen Nginx-Host mit dem folgenden Befehl:

ln -s /etc/nginx/sites-available/flask.conf /etc/nginx/sites-enabled/

Starte abschließend den Nginx-Dienst neu, um die Änderungen zu übernehmen:

systemctl restart nginx

Jetzt ist Nginx so konfiguriert, dass es deine Flask-Anwendung bedienen kann.

Flask-Anwendung mit Let’s Encrypt SSL sichern

Als Nächstes empfiehlt es sich, deine Anwendung mit dem kostenlosen SSL von Let’s Encrypt zu sichern. Zunächst musst du den Certbot-Client installieren, um das SSL-Zertifikat zu installieren und zu verwalten. Du kannst ihn mit dem folgenden Befehl installieren:

apt-get install python3-certbot-nginx -y

Nach der Installation sicherst du deine Website mit Let’s Encrypt SSL, indem du den folgenden Befehl ausführst:

certbot --nginx -d flask.example.com

Du wirst aufgefordert, eine gültige E-Mail-Adresse anzugeben und die Nutzungsbedingungen zu akzeptieren (siehe unten):

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): [email protected]

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for flask.example.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/flask.conf

Als Nächstes wählst du aus, ob der HTTP-Datenverkehr auf HTTPS umgeleitet werden soll oder nicht (siehe unten):

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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): 2

Gib 2 ein und drücke die Eingabetaste, um die Installation abzuschließen. Du solltest die folgende Ausgabe sehen:

Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/flask.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://flask.example.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=flask.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/flask.example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/flask.example.com/privkey.pem
   Your cert will expire on 2020-10-30. 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

 - We were unable to subscribe you the EFF mailing list because your
   e-mail address appears to be invalid. You can try again later by
   visiting https://act.eff.org.

Jetzt ist deine Flask-Website mit Let’s Encrypt SSL gesichert. Du kannst deine Flask-Anwendung über die URL https://flask.example.com aufrufen .

Fazit

Herzlichen Glückwunsch! Du hast die Flask-Anwendung erfolgreich mit uWSGI und Nginx eingerichtet und mit Let’s Encrypt SSL gesichert. Jetzt kannst du deine Python-Anwendung ganz einfach mit Flask entwickeln und einsetzen. Wenn du noch Fragen hast, kannst du dich gerne an mich wenden.

Das könnte dich auch interessieren …