Einführung
In diesem Handbuch erstellen Sie eine Python-Anwendung mit dem Flask-Mikroframework unter Ubuntu 18.04. Der Hauptteil dieses Artikels befasst sich mit dem Einrichten vonGunicorn application server und dem Starten der Anwendung sowie dem Konfigurieren vonNginx als Front-End-Reverse-Proxy.
Voraussetzungen
Bevor Sie mit diesem Handbuch beginnen, sollten Sie Folgendes haben:
-
Ein Server mit Ubuntu 18.04 und einem Nicht-Root-Benutzer mit Sudo-Rechten. Befolgen Sie unsereinitial server setup guide als Anleitung.
-
Nginx wird gemäß den Schritten 1 und 2 vonHow To Install Nginx on Ubuntu 18.04 installiert.
-
Ein Domänenname, der so konfiguriert ist, dass er auf Ihren Server verweist. Sie können einen aufNamecheap kaufen oder einen kostenlos aufFreenom erhalten. Sie können lernen, wie Sie Domains auf DigitalOcean verweisen, indem Sie die relevantendocumentation on domains and DNS befolgen. Stellen Sie sicher, dass Sie die folgenden DNS-Einträge erstellen:
-
Ein A-Datensatz mit
your_domain
, der auf die öffentliche IP-Adresse Ihres Servers verweist. -
Ein A-Datensatz mit
www.your_domain
, der auf die öffentliche IP-Adresse Ihres Servers verweist.
-
-
Kenntnis der WSGI-Spezifikation, mit der der Gunicorn-Server mit Ihrer Flask-Anwendung kommuniziert. This discussion behandelt WSGI ausführlicher.
[[Schritt 1 - Installieren der Komponenten aus den Ubuntu-Repositorys]] == Schritt 1 - Installieren der Komponenten aus den Ubuntu-Repositorys
Unser erster Schritt wird darin bestehen, alle benötigten Teile aus den Ubuntu-Repositories zu installieren. Dies beinhaltetpip
, den Python-Paketmanager, der unsere Python-Komponenten verwaltet. Wir erhalten auch die Python-Entwicklungsdateien, die zum Erstellen einiger Gunicorn-Komponenten erforderlich sind.
Zuerst aktualisieren wir den lokalen Paketindex und installieren die Pakete, mit denen wir unsere Python-Umgebung erstellen können. Dazu gehörenpython3-pip
sowie einige weitere Pakete und Entwicklungstools, die für eine robuste Programmierumgebung erforderlich sind:
sudo apt update
sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools
Lassen Sie uns mit diesen Paketen fortfahren und eine virtuelle Umgebung für unser Projekt erstellen.
[[Schritt-2 - Erstellen einer Python-virtuellen Umgebung]] == Schritt 2 - Erstellen einer virtuellen Python-Umgebung
Als Nächstes richten wir eine virtuelle Umgebung ein, um unsere Flask-Anwendung von den anderen Python-Dateien auf dem System zu isolieren.
Beginnen Sie mit der Installation des Paketspython3-venv
, mit dem das Modulvenv
installiert wird:
sudo apt install python3-venv
Als nächstes erstellen wir ein übergeordnetes Verzeichnis für unser Flask-Projekt. Wechseln Sie in das Verzeichnis, nachdem Sie es erstellt haben:
mkdir ~/myproject
cd ~/myproject
Erstellen Sie eine virtuelle Umgebung zum Speichern der Python-Anforderungen Ihres Flask-Projekts, indem Sie Folgendes eingeben:
python3.6 -m venv myprojectenv
Dadurch wird eine lokale Kopie von Python undpip
in einem Verzeichnis namensmyprojectenv
in Ihrem Projektverzeichnis installiert.
Vor der Installation von Anwendungen in der virtuellen Umgebung müssen Sie diese aktivieren. Geben Sie dazu Folgendes ein:
source myprojectenv/bin/activate
Ihre Eingabeaufforderung ändert sich und zeigt an, dass Sie jetzt in der virtuellen Umgebung arbeiten. Es sieht ungefähr so aus:(myprojectenv)user@host:~/myproject$
.
[[Schritt-3 -—- Einrichten einer Kolbenanwendung]] == Schritt 3 - Einrichten einer Kolbenanwendung
Jetzt, da Sie sich in Ihrer virtuellen Umgebung befinden, können Sie Flask und Gunicorn installieren und mit dem Entwerfen Ihrer Anwendung beginnen.
Installieren wir zunächstwheel
mit der lokalen Instanz vonpip
, um sicherzustellen, dass unsere Pakete auch dann installiert werden, wenn Radarchive fehlen:
pip install wheel
Note
[.note] # Unabhängig davon, welche Python-Version Sie verwenden, sollten Sie bei Aktivierung der virtuellen Umgebung den Befehlpip
verwenden (nichtpip3
).
#
Als nächstes installieren wir Flask und Gunicorn:
pip install gunicorn flask
Beispiel-App erstellen
Nachdem Sie Flask zur Verfügung haben, können Sie eine einfache Anwendung erstellen. Flask ist ein Mikro-Framework. Es enthält nicht viele der Tools, die für umfassendere Frameworks geeignet sind, und ist hauptsächlich als Modul vorhanden, das Sie in Ihre Projekte importieren können, um Sie bei der Initialisierung einer Webanwendung zu unterstützen.
Während Ihre Anwendung möglicherweise komplexer ist, erstellen wir unsere Flask-App in einer einzigen Datei mit dem Namenmyproject.py
:
nano ~/myproject/myproject.py
Der Anwendungscode wird in dieser Datei gespeichert. Es wird Flask importiert und ein Flask-Objekt instanziiert. Hiermit können Sie die Funktionen 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 "Hello There!
"
if __name__ == "__main__":
app.run(host='0.0.0.0')
Dies definiert im Wesentlichen, welcher Inhalt angezeigt wird, wenn auf die Stammdomäne zugegriffen wird. Speichern und schließen Sie die Datei, wenn Sie fertig sind.
Wenn Sie die anfängliche Anleitung zur Serverkonfiguration befolgt haben, sollte eine UFW-Firewall aktiviert sein. Um die Anwendung zu testen, müssen Sie den Zugriff auf Port5000
zulassen:
sudo ufw allow 5000
Jetzt können Sie Ihre Flask-App testen, indem Sie Folgendes eingeben:
python myproject.py
Es wird die folgende Ausgabe angezeigt, einschließlich einer hilfreichen Warnung, die Sie daran erinnert, dieses Server-Setup 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 so etwas sehen:
Wenn Sie fertig sind, drücken SieCTRL-C
in Ihrem Terminalfenster, um den Flask-Entwicklungsserver zu stoppen.
Erstellen des WSGI-Einstiegspunkts
Als Nächstes erstellen wir eine Datei, die als Einstiegspunkt für unsere Anwendung dient. Dies teilt unserem Gunicorn-Server mit, wie er mit der Anwendung interagieren soll.
Nennen wir die Dateiwsgi.py
:
nano ~/myproject/wsgi.py
Importieren Sie in dieser Datei die Flask-Instanz aus unserer Anwendung und führen Sie 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 - Konfigurieren des Gunicorns]] == Schritt 4 - Konfigurieren des Gunicorns
Ihre Bewerbung wird nun mit einem Einstiegspunkt erstellt. Jetzt können wir mit der Konfiguration von Gunicorn fortfahren.
Bevor wir fortfahren, sollten wir überprüfen, ob Gunicorn die Anwendung korrekt bedienen kann.
Wir können dies tun, indem wir einfach den Namen unseres Einstiegspunkts übergeben. Dies besteht aus dem Namen des Moduls (abzüglich der Erweiterung.py
) plus dem Namen des aufrufbaren Moduls in der Anwendung. In unserem Fall ist dieswsgi:app
.
Wir geben auch die Schnittstelle und den Port an, an den die Verbindung hergestellt werden soll, damit die Anwendung auf einer öffentlich verfügbaren Schnittstelle gestartet wird:
cd ~/myproject
gunicorn --bind 0.0.0.0:5000 wsgi:app
Die Ausgabe sollte folgendermaßen aussehen:
Output[2018-07-13 19:35:13 +0000] [28217] [INFO] Starting gunicorn 19.9.0
[2018-07-13 19:35:13 +0000] [28217] [INFO] Listening at: http://0.0.0.0:5000 (28217)
[2018-07-13 19:35:13 +0000] [28217] [INFO] Using worker: sync
[2018-07-13 19:35:13 +0000] [28220] [INFO] Booting worker with pid: 28220
Besuchen Sie die IP-Adresse Ihres Servers, wobei:5000
in Ihrem Webbrowser erneut an das Ende angehängt ist:
http://your_server_ip:5000
Sie sollten die Ausgabe Ihrer Anwendung sehen:
Wenn Sie bestätigt haben, dass es ordnungsgemäß funktioniert, drücken SieCTRL-C
in Ihrem Terminalfenster.
Wir sind jetzt mit unserer virtuellen Umgebung fertig und können sie deaktivieren:
deactivate
Alle Python-Befehle verwenden jetzt wieder die Python-Umgebung des Systems.
Als nächstes erstellen wir die systemd-Service-Unit-Datei. Durch das Erstellen einer System-Unit-Datei kann Ubuntus Init-System Gunicorn automatisch starten und die Flask-Anwendung bei jedem Start des Servers bedienen.
Erstellen Sie eine Einheitendatei mit der Endung.service
im Verzeichnis/etc/systemd/system
, um zu beginnen:
sudo nano /etc/systemd/system/myproject.service
Im Inneren beginnen wir mit dem Abschnitt[Unit]
, in dem Metadaten und Abhängigkeiten angegeben werden. Fügen Sie hier eine Beschreibung unseres Dienstes ein und weisen Sie das init-System an, diese erst zu starten, nachdem das Netzwerkziel erreicht wurde:
/etc/systemd/system/myproject.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
Als nächstes öffnen wir den Abschnitt[Service]
. Dies gibt den Benutzer und die Gruppe an, unter denen der Prozess ausgeführt werden soll. Geben Sie unserem regulären Benutzerkonto den Besitz des Prozesses, da ihm alle relevanten Dateien gehören. Geben wir der Gruppewww-data
auch Gruppenbesitz, damit Nginx problemlos mit den Gunicorn-Prozessen kommunizieren kann. Denken Sie daran, den Benutzernamen hier durch Ihren Benutzernamen 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 ordnen wir das Arbeitsverzeichnis zu und legen die UmgebungsvariablePATH
fest, damit das Init-System weiß, dass sich die ausführbaren Dateien für den Prozess in unserer virtuellen Umgebung befinden. Geben Sie auch den Befehl zum Starten des Dienstes an. Dieser Befehl führt Folgendes aus:
-
Starten Sie 3 Worker-Prozesse (obwohl Sie dies nach Bedarf anpassen sollten)
-
Erstellen und binden Sie eine Unix-Socket-Datei
myproject.sock
in unserem Projektverzeichnis. Wir setzen einen umask-Wert von007
, damit die Socket-Datei erstellt wird, die den Zugriff auf den Eigentümer und die Gruppe ermöglicht, während der andere Zugriff eingeschränkt wird -
Geben Sie den Namen der WSGI-Einstiegspunktdatei zusammen mit dem in dieser Datei aufrufbaren Python an (
wsgi:app
).
Systemd erfordert, dass wir den vollständigen Pfad zur ausführbaren Datei von Gunicorn angeben, die in unserer virtuellen Umgebung installiert ist.
Denken Sie daran, den Benutzernamen und die Projektpfade 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
Zum Schluss fügen wir einen Abschnitt[Install]
hinzu. Dies teilt systemd mit, mit was dieser Dienst verknüpft werden soll, wenn er beim Booten gestartet werden kann. Wir möchten, dass dieser Dienst gestartet wird, wenn das reguläre Mehrbenutzersystem ausgeführt wird:
/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
Damit ist unsere systemd-Servicedatei vollständig. Speichern und schließen Sie es jetzt.
Wir können jetzt den von uns erstellten Gunicorn-Dienst starten und aktivieren, sodass er beim Booten startet:
sudo systemctl start myproject
sudo systemctl enable myproject
Überprüfen wir den Status:
sudo systemctl status myproject
Sie sollten die Ausgabe so sehen:
Output● myproject.service - Gunicorn instance to serve myproject
Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2018-07-13 14:28:39 UTC; 46s ago
Main PID: 28232 (gunicorn)
Tasks: 4 (limit: 1153)
CGroup: /system.slice/myproject.service
├─28232 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007
├─28250 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007
├─28251 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007
└─28252 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007
Wenn Fehler auftreten, müssen Sie diese beheben, bevor Sie mit dem Lernprogramm fortfahren.
[[Schritt-5 - Konfigurieren von Nginx-zu-Proxy-Anforderungen]] == Schritt 5 - Konfigurieren von Nginx zu Proxy-Anforderungen
Unser Gunicorn-Anwendungsserver sollte nun betriebsbereit sein und auf Anforderungen in der Socket-Datei im Projektverzeichnis warten. Lassen Sie uns nun Nginx so konfigurieren, dass Webanforderungen an diesen Socket weitergeleitet werden, indem Sie einige kleine Änderungen an der Konfigurationsdatei vornehmen.
Beginnen Sie mit der Erstellung einer neuen Serverblock-Konfigurationsdatei imsites-available
-Verzeichnis von Nginx. Nennen wir diesemyproject
, um mit dem Rest des Handbuchs Schritt zu halten:
sudo nano /etc/nginx/sites-available/myproject
Öffnen Sie einen Serverblock und weisen Sie Nginx an, den Standardport80
abzuhören. Sagen wir ihm auch, dass er diesen Block für Anfragen nach dem Domain-Namen unseres Servers verwenden soll:
/etc/nginx/sites-available/myproject
server {
listen 80;
server_name your_domain www.your_domain;
}
Als nächstes fügen wir einen Standortblock hinzu, der zu jeder Anfrage passt. In diesem Block enthalten wir die Dateiproxy_params
, in der einige allgemeine Proxy-Parameter angegeben sind, die festgelegt werden müssen. Anschließend übergeben wir die Anforderungen an den Socket, den wir mit der Direktiveproxy_pass
definiert haben:
/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.
Verknüpfen Sie die Datei mit dem Verzeichnissites-enabled
, um die soeben erstellte Nginx-Serverblockkonfiguration zu aktivieren:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Mit der Datei in diesem Verzeichnis können Sie nach Syntaxfehlern suchen:
sudo nginx -t
Wenn dies ohne Hinweis auf ein Problem erneut auftritt, starten Sie den Nginx-Prozess neu, um die neue Konfiguration zu lesen:
sudo systemctl restart nginx
Passen wir zum Schluss die Firewall erneut an. Wir brauchen keinen Zugriff mehr über Port5000
, daher können wir diese Regel entfernen. Wir können dann den vollen Zugriff auf den Nginx-Server erlauben:
sudo ufw delete allow 5000
sudo ufw allow 'Nginx Full'
Sie sollten nun in der Lage sein, in Ihrem Webbrowser zum Domainnamen Ihres Servers zu navigieren:
http://your_domain
Sie sollten die Ausgabe Ihrer Anwendung sehen:
Wenn Sie auf Fehler stoßen, überprüfen Sie Folgendes:
-
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]] == Schritt 6 - Sichern der Anwendung
Um sicherzustellen, dass der Datenverkehr zu Ihrem Server sicher bleibt, fordern wir ein SSL-Zertifikat für Ihre Domain an. Es gibt mehrere Möglichkeiten, dies zu tun, einschließlich des Abrufs eines kostenlosen Zertifikats vonLet’s Encrypt,generating a self-signed certificate oderbuying one from another provider und der Konfiguration von Nginx für die Verwendung, indem Sie die Schritte 2 bis 6 vonHow to Create a Self-signed SSL Certificate for Nginx in Ubuntu 18.04 ausführen . Wir werden aus Gründen der Zweckmäßigkeit die erste Option wählen.
Fügen Sie zunächst das Certbot Ubuntu-Repository hinzu:
sudo add-apt-repository ppa:certbot/certbot
Sie müssenENTER
drücken, um zu akzeptieren.
Installieren Sie das Nginx-Paket von Certbot mitapt
:
sudo apt install python-certbot-nginx
Certbot bietet verschiedene Möglichkeiten, SSL-Zertifikate über Plugins abzurufen. Das Nginx-Plugin kümmert sich darum, Nginx neu zu konfigurieren und die Konfiguration bei Bedarf neu zu laden. Geben Sie Folgendes ein, um dieses Plugin zu verwenden:
sudo certbot --nginx -d your_domain -d www.your_domain
Dadurch wirdcertbot
mit dem Plugin--nginx
ausgeführt, wobei-d
verwendet wird, um die Namen anzugeben, für die das Zertifikat gültig sein soll.
Wenn Siecertbot
zum ersten Mal ausführen, werden Sie aufgefordert, eine E-Mail-Adresse einzugeben und den Nutzungsbedingungen zuzustimmen. Danach kommuniziertcertbot
mit dem Let's Encrypt-Server und führt dann eine Herausforderung aus, um zu überprüfen, ob Sie die Domäne steuern, für die Sie ein Zertifikat anfordern.
Wenn dies erfolgreich ist, werden Sie voncertbot
gefragt, wie Sie Ihre HTTPS-Einstellungen konfigurieren möchten:
OutputPlease 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 und drücken SieENTER
. Die Konfiguration wird aktualisiert und Nginx wird neu geladen, um die neuen Einstellungen zu übernehmen. certbot
wird mit einer Nachricht abgeschlossen, die Ihnen mitteilt, dass der Prozess erfolgreich war und wo Ihre Zertifikate gespeichert sind:
OutputIMPORTANT 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 2018-07-23. 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 die Nginx-Installationsanweisungen in den Voraussetzungen befolgt haben, benötigen Sie nicht mehr die redundante HTTP-Profilerlaubnis:
sudo ufw delete allow 'Nginx HTTP'
Navigieren Sie zum Überprüfen der Konfiguration erneut mithttps://
zu Ihrer Domain:
https://your_domain
Sie sollten Ihre Anwendungsausgabe erneut sehen, zusammen mit der Sicherheitsanzeige Ihres Browsers, die darauf hinweist, dass die Site gesichert ist.
Fazit
In diesem Handbuch haben Sie eine einfache Flask-Anwendung in einer virtuellen Python-Umgebung erstellt und gesichert. Sie haben einen WSGI-Einstiegspunkt erstellt, damit jeder WSGI-fähige Anwendungsserver mit ihm kommunizieren kann, und dann den Gunicorn-App-Server so konfiguriert, dass er diese Funktion bereitstellt. Anschließend haben Sie eine systemd-Servicedatei erstellt, um den Anwendungsserver beim Booten automatisch zu starten. Sie haben auch einen Nginx-Serverblock erstellt, der den Webclient-Datenverkehr an den Anwendungsserver weiterleitet, externe Anforderungen weiterleitet und den Datenverkehr mit Let's Encrypt an Ihren Server sichert.
Flask ist ein sehr einfaches, aber äußerst flexibles Framework, mit dem Sie Ihre Anwendungen mit Funktionen versehen können, ohne die Struktur und das Design zu stark einzuschränken. Mit dem in diesem Handbuch beschriebenen allgemeinen Stapel können Sie die von Ihnen entworfenen Kolbenanwendungen bedienen.