Bereitstellen von Web2py-Python-Anwendungen mit uWSGI und Nginx unter Ubuntu 14.04

Einführung

Das web2py-Framework ist ein leistungsstarkes und benutzerfreundliches Tool für die schnelle Entwicklung von Python-Webanwendungen mit vollem Funktionsumfang. Mit web2py können Sie Ihre Anwendungen auf einfache Weise mithilfe einer administrativen Web-Benutzeroberfläche entwickeln und verwalten.

In diesem Handbuch wird gezeigt, wie eine web2py-Anwendung unter Ubuntu 14.04 bereitgestellt wird. Wir werden den uWSGI-Anwendungsserver verwenden, um mit der Anwendung über mehrere Arbeitsprozesse zu kommunizieren. Vor uWSGI werden wir Nginx in einer Reverse-Proxy-Konfiguration einrichten, um die tatsächlichen Client-Verbindungen zu handhaben. Dies ist eine wesentlich robustere Bereitstellungsstrategie als die alleinige Verwendung des web2py-Servers oder von uWSGI.

Voraussetzungen und Ziele

Um dieses Handbuch zu vervollständigen, sollten Sie eine neue Ubuntu 14.04-Serverinstanz mit einem Nicht-Root-Benutzer haben, der über die Berechtigung "+ sudo +" verfügt. Informationen zum Einrichten finden Sie in unserem initial server setup guide.

Wir werden das web2py-Framework herunterladen und es testen, um sicherzustellen, dass die Standardanwendungsumgebung ordnungsgemäß funktioniert. Anschließend werden wir den uWSGI-Anwendungscontainer herunterladen und installieren, der als Schnittstelle zwischen Anforderungen und dem web2py-Python-Code dient. Wir werden Nginx davor einrichten, damit es Client-Verbindungen und Proxy-Anfragen an uWSGI verarbeiten kann. Wir werden jede unserer Komponenten so konfigurieren, dass sie beim Booten starten, um die Notwendigkeit administrativer Eingriffe zu minimieren.

Laden Sie das web2py Framework herunter

Unser erster Schritt ist das Herunterladen des eigentlichen web2py-Frameworks. Dies wird in einem "+ git " - Repository auf GitHub gepflegt. Der beste Weg, es herunterzuladen, ist " git +".

Wir können + git + von den Standard-Ubuntu-Repositories herunterladen und installieren, indem wir Folgendes eingeben:

sudo apt-get update
sudo apt-get install git

Sobald "+ git " installiert ist, können wir das Repository in das Ausgangsverzeichnis unseres Benutzers klonen. Wir können die Anwendung beliebig benennen. In unserem Beispiel verwenden wir der Einfachheit halber den Namen "+". Wir müssen das rekursive Flag "+ -" hinzufügen, da die Datenbankabstraktionsschicht als eigenes Submodul "+ git +" behandelt wird:

git clone --recursive https://github.com/web2py/web2py.git ~/

Das web2py-Framework wird in ein Verzeichnis mit dem Namen "+ myapp +" in Ihrem Home-Verzeichnis heruntergeladen.

Wir können die Standardanwendung testen, indem wir in das Verzeichnis wechseln:

cd ~/

Die Verwaltungsschnittstelle muss durch SSL gesichert sein, damit wir ein einfaches selbstsigniertes Zertifikat erstellen können, um dies zu testen. Erstellen Sie den Serverschlüssel und das Zertifikat, indem Sie Folgendes eingeben:

openssl req -x509 -new -newkey rsa:4096 -days 3652 -nodes -keyout .key -out .crt

Sie müssen einige Informationen für das Zertifikat ausfüllen, das Sie generieren. Der einzige Teil, der in diesem Fall tatsächlich von Bedeutung ist, ist das Feld "+ Common Name +", das auf den Domainnamen oder die IP-Adresse Ihres Servers verweisen sollte:

. . .

Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:[email protected]

Wenn Sie fertig sind, sollten sich ein SSL-Schlüssel und ein Zertifikat in Ihrem Anwendungsverzeichnis befinden. Diese werden als "+ .key " bzw. " .crt +" bezeichnet.

Danach können wir das web2py-Webinterface starten, um es zu testen. Dazu können wir Folgendes eingeben:

python web2py.py -k .key -c .crt -i 0.0.0.0 -p 8000

Sie werden aufgefordert, ein Kennwort für die Verwaltungsschnittstelle auszuwählen.

Jetzt können Sie Ihre Anwendung in Ihrem Webbrowser aufrufen, indem Sie zu folgender Adresse navigieren:

https://:8000

Stellen Sie sicher, dass Sie in der obigen Adresse "+ https " anstelle von " http +" verwenden. Sie werden gewarnt, dass Ihr Browser das SSL-Zertifikat nicht erkennt:

Dies wird erwartet, da wir unser eigenes Zertifikat unterschrieben haben. Klicken Sie auf den Link "Erweitert" oder auf einen anderen Link, den Ihnen Ihr Browser gibt, und fahren Sie dann wie geplant mit der Website fort. Sie sehen die web2py-Oberfläche:

Wenn Sie ganz rechts auf die Schaltfläche "Administrationsoberfläche" klicken, sollten Sie in der Lage sein, das Kennwort einzugeben, das Sie beim Ausführen des Servers ausgewählt haben, und zur Administrationssite zu gelangen:

Auf diese Weise erhalten Sie Zugriff auf den eigentlichen Code, mit dem Ihre Anwendungen ausgeführt werden, und können die Dateien über die Benutzeroberfläche selbst bearbeiten und optimieren.

Wenn Sie fertig sind, geben Sie CTRL-C in Ihr Terminalfenster ein. Wir haben unsere Anwendung getestet und gezeigt, dass auf sie im Web zugegriffen werden kann, wenn der web2py-Entwicklungsserver ausgeführt wird.

Installieren und konfigurieren Sie uWSGI

Nachdem die web2py-Anwendung nun betriebsbereit ist, können wir uWSGI konfigurieren. uWSGI ist ein Anwendungsserver, der über eine Standardschnittstelle namens WSGI mit Anwendungen kommunizieren kann. Weitere Informationen hierzu finden Sie unter https://www.digitalocean.com/community/tutorials/how-to-set-up-uwsgi-and-nginx-to-serve-python-apps-on-ubuntu-14-04 # Definitionen und Konzepte [dieser Abschnitt] unseres Handbuchs zum Einrichten von uWSGI und Nginx unter Ubuntu 14.04.

UWSGI installieren

Im Gegensatz zu der oben verlinkten Anleitung installieren wir in diesem Lernprogramm uWSGI global. Bevor wir uWSGI installieren können, müssen wir + pip +, den Python-Paketmanager und die Python-Entwicklungsdateien installieren, auf die sich uWSGI stützt. Wir können diese direkt aus den Ubuntu-Repositories installieren:

sudo apt-get install python-pip python-dev

Jetzt können wir uWSGI global mit + pip + installieren, indem wir Folgendes eingeben:

sudo pip install uwsgi

Der uWSGI-Anwendungscontainerserver ist über die WSGI-Schnittstellenspezifikation mit Python-Anwendungen verbunden. Das web2py-Framework enthält eine Datei, die diese Schnittstelle im Verzeichnis + handlers + bereitstellt. Um die Datei zu verwenden, müssen wir sie aus dem Verzeichnis in das Hauptprojektverzeichnis verschieben:

mv ~//handlers/wsgihandler.py ~/

Mit dem WSGI-Handler im Hauptprojektverzeichnis können wir überprüfen, ob uWSGI die Anwendung bedienen kann, indem wir Folgendes eingeben:

uwsgi --http :8000 --chdir ~/ -w wsgihandler:application

Dadurch sollte die Anwendung auf Port 8000 erneut gestartet werden. Dieses Mal wird das SSL-Zertifikat und der SSL-Schlüssel nicht über HTTP, sondern über HTTPS bereitgestellt. Sie können dies in Ihrem Browser erneut mit dem Protokoll "+ http +" testen. Sie können die Administrationsoberfläche nicht testen, da dies von web2py deaktiviert wird, wenn keine Verschlüsselung verfügbar ist.

Wenn Sie fertig sind, geben Sie STRG-C in Ihr Terminalfenster ein, um den Server zu stoppen.

Erstellen einer uWSGI-Konfigurationsdatei

Nachdem wir wissen, dass uWSGI die Anwendung bedienen kann, können wir eine uWSGI-Konfigurationsdatei mit den Informationen unserer Anwendung erstellen.

Erstellen Sie ein Verzeichnis unter "+ / etc / uwsgi / sites +", um unsere Konfigurationen zu speichern, und verschieben Sie es in dieses Verzeichnis:

sudo mkdir -p /etc/uwsgi/sites
cd /etc/uwsgi/sites

Wir werden unsere Konfigurationsdatei "+ myapp.ini +" aufrufen:

sudo nano .ini

In der Konfigurationsdatei müssen wir mit einem "+ [uwsgi] +" - Header beginnen, unter dem alle unsere Konfigurationsanweisungen abgelegt werden. Nach dem Header geben wir den Verzeichnispfad unserer Anwendung an und teilen ihm das auszuführende Modul mit. Dies sind die gleichen Informationen, die wir zuvor in der Befehlszeile verwendet haben. Sie müssen die Modulzeile nicht ändern:

[uwsgi]
chdir = /home//
module = wsgihandler:application

Als nächstes müssen wir festlegen, dass uWSGI im Master-Modus betrieben werden soll. Wir wollen fünf Worker-Prozesse erzeugen:

[uwsgi]
chdir = /home//
module = wsgihandler:application

master = true
processes = 5

Als nächstes müssen wir festlegen, wie uWSGI Verbindungen erhalten soll. In unserem Test des uWSGI-Servers haben wir normale HTTP-Verbindungen akzeptiert. Da wir Nginx jedoch als Reverse-Proxy vor uWSGI konfigurieren, haben wir andere Optionen. Nginx kann Proxys mit dem Protokoll "+ uwsgi +" erstellen, einem schnellen Binärprotokoll, das von uWSGI für die Kommunikation mit anderen Servern entwickelt wurde. Wir kommunizieren mit diesem Protokoll. Dies ist die Standardeinstellung, wenn wir kein anderes Protokoll angeben.

Da wir mit Nginx über das Protokoll "+ uwsgi +" kommunizieren, benötigen wir keinen Netzwerkanschluss. Stattdessen verwenden wir einen Unix-Socket, der sicherer und schneller ist. Wir werden dies in unserem Bewerbungsverzeichnis ablegen. Wir müssen die Berechtigungen ändern, damit die Gruppe lesen und in den Socket schreiben kann. In Kürze geben wir der Nginx-Prozessgruppe den Besitz des Sockets, damit uWSGI und Nginx über den Socket kommunizieren können:

[uwsgi]
chdir = /home//
module = wsgihandler:application

master = true
processes = 5

socket = /home///.sock
chmod-socket = 660
vacuum = true

Die oben stehende Direktive "+ vacuum +" bereinigt die Socket-Datei, wenn der uWSGI-Prozess endet.

Unsere uWSGI-Konfigurationsdatei ist jetzt vollständig. Speichern und schließen Sie die Datei.

Erstellen Sie eine uWSGI-Upstart-Datei

Wir haben eine Konfigurationsdatei für uWSGI erstellt, aber unseren Anwendungsserver noch nicht so eingerichtet, dass er beim Booten automatisch startet. Um diese Funktionalität zu implementieren, können wir eine einfache Upstart-Datei erstellen. Wir werden ihn anweisen, uWSGI im „Emperor-Modus“ auszuführen, wodurch der Anwendungsserver eine beliebige Anzahl von Konfigurationen lesen und den Server für jede Konfiguration starten kann.

Erstellen Sie eine Datei im Verzeichnis "+ / etc / init +", in der der Upstart-Prozess nach seinen Konfigurationsdateien sucht:

sudo nano /etc/init/uwsgi.conf

Zunächst geben wir unserer Servicedatei eine Beschreibung und geben an, auf welchen Runleveln sie automatisch gestartet werden soll. Die herkömmlichen Mehrbenutzer-Runlevel sind 2, 3, 4 und 5. Wir werden Upstart veranlassen, den Dienst zu stoppen, wenn der Server zu einem anderen Runlevel wechselt (wie zum Beispiel während des Herunterfahrens, Neustarts oder Einzelbenutzermodus):

description "uWSGI application server in Emperor mode"

start on runlevel [2345]
stop on runlevel [!2345]

Als Nächstes müssen Sie den Benutzer und die Gruppe angeben, unter denen der Prozess ausgeführt werden soll. Wir werden unser normales Benutzerkonto verwenden, da es alle unsere Projektdateien besitzt. Für unsere Gruppe müssen wir die Gruppenzugehörigkeit "+ www-data" zulassen. Dies ist die Gruppe, unter der Nginx operiert. Auf diese Weise kann der Webserver frei mit uWSGI kommunizieren, da unsere uWSGI-Konfiguration der Socket-Gruppe Lese- und Schreibrechte erteilt hat.

Danach müssen wir nur noch den Befehl angeben, der ausgeführt werden soll, um uWSGI zu starten. Wir müssen nur das "+ - Emperor +" -Flag verwenden und es an das Verzeichnis übergeben, das unsere Konfigurationsdatei enthält:

description "uWSGI application server in Emperor mode"

start on runlevel [2345]
stop on runlevel [!2345]

setuid
setgid www-data

exec /usr/local/bin/uwsgi --emperor /etc/uwsgi/sites

Dadurch wird ein uWSGI-Anwendungsserver gestartet, der unsere web2py-Site verwaltet. Im Emperor-Modus können Konfigurationsdateien in diesem Verzeichnis problemlos für andere Projekte hinzugefügt werden. Sie werden automatisch behandelt.

Wir sind jetzt mit unserem Upstart-Skript fertig. Speichern und schließen Sie die Datei. Zu diesem Zeitpunkt können wir den uWSGI-Dienst nicht starten, da wir Nginx noch nicht installiert haben. Dies bedeutet, dass die Gruppe, unter der unser Skript ausgeführt werden soll, noch nicht verfügbar ist.

Installieren und konfigurieren Sie Nginx als Reverse Proxy

Nachdem uWSGI konfiguriert und einsatzbereit ist, können wir jetzt Nginx als unseren Reverse-Proxy installieren und konfigurieren. Dies kann von Ubuntus Standard-Repositorys heruntergeladen werden:

sudo apt-get install nginx

Sobald Nginx installiert ist, können wir die Serverblockkonfiguration ändern. Wir werden den Standard-Serverblock als Basis verwenden, da er das meiste enthält, was wir brauchen:

sudo nano /etc/nginx/sites-available/default

Die web2py-Anwendung erkennt, ob Sie eine Verbindung mit normalem HTTP oder mit SSL-Verschlüsselung herstellen. Aus diesem Grund enthält unsere Datei tatsächlich jeweils einen Serverblock. Wir beginnen mit dem Serverblock, der für den Betrieb an Port 80 konfiguriert ist.

Ändern Sie "+ Servername ", um auf den Domainnamen oder die IP-Adresse zu verweisen, auf die Ihre Site zugreifen soll. Danach erstellen wir einen ` location {} ` Block, der Anfragen nach statischem Inhalt entspricht. Grundsätzlich möchten wir reguläre Ausdrücke verwenden, um Anforderungen, die mit " / static / " enden, mit einer vorhergehenden Pfadkomponente abzugleichen. Wir möchten diese Anforderungen dem Verzeichnis " applications +" in unserem web2py-Projekt zuordnen. Stellen Sie sicher, dass Sie auf das Basisverzeichnis und den App-Namen Ihres Benutzers verweisen:

server {
   listen 80 default_server;
   listen [::]:80 default_server ipv6only=on;

   root /usr/share/nginx/html;
   index index.html index.htm;

   server_name ;





   . . .

Danach müssen wir den + location / {} + Block anpassen, um Anfragen an unseren uWSGI-Socket weiterzuleiten. Wir müssen nur die mit Nginx gepackte uWSGI-Parameterdatei einfügen und die Anforderungen an den von uns konfigurierten Socket übergeben (in unserer uWSGI-Datei + .ini +):

server {
   listen 80 default_server;
   listen [::]:80 default_server ipv6only=on;

   root /usr/share/nginx/html;
   index index.html index.htm;

   server_name ;

   location ~* /(\w+)/static/ {
       root /home///applications/;
   }

   location / {


   }
}

Dies ist alles, was wir für unseren ersten Serverblock benötigen.

Am Ende der Datei befindet sich ein auskommentierter Abschnitt mit den meisten Anweisungen, die zum Bereitstellen von Inhalten mit SSL erforderlich sind. Sie können diesen Block identifizieren, da er als erste Direktive "+ listen 443; +" enthält. Kommentieren Sie diesen Block aus, um mit der Konfiguration zu beginnen.

Ändern Sie zunächst das Zeichen "+ Servername " erneut, um es mit dem Domänennamen oder der IP-Adresse Ihres Servers abzugleichen. Wir können dann zu den Direktiven " ssl_certificate " und " ssl_certificate_key " springen. Die von uns erzeugten SSL-Zertifikate werden vorübergehend in ein Verzeichnis unter " / etc / nginx / ssl +" gestellt. Geben Sie daher den Pfad zu den Dateien an diesem Speicherort an:

server {
   listen 443;
   server_name ;

   root html;
   index index.html index.htm;

   ssl on;
   ssl_certificate ;
   ssl_certificate_key ;

   . . .

Entfernen Sie in der Liste "+ ssl_protocols +" SSLv3, da festgestellt wurde, dass das Protokoll selbst Schwachstellen aufweist.

Wir können dann zum + location / {} + Block springen und die gleichen uWSGI-Proxy-Informationen wie im letzten Serverblock einfügen:

server {
   listen 443;
   server_name ;

   root html;
   index index.html index.htm;

   ssl on;
   ssl_certificate /etc/nginx/ssl/.crt;
   ssl_certificate_key /etc/nginx/ssl/.key;

   ssl_session_timeout 5m;

   ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
   ssl_prefer_server_ciphers on;

   location / {


   }
}

In dieser Datei sollten nun zwei Serverblöcke konfiguriert sein. Speichern und schließen Sie es, wenn Sie fertig sind.

Letzte Schritte

Als nächstes müssen wir die SSL-Zertifikate in das von uns angegebene Verzeichnis verschieben. Erstellen Sie zuerst das Verzeichnis:

sudo mkdir -p /etc/nginx/ssl

Verschieben Sie nun das Zertifikat und den Schlüssel, die Sie erstellt haben, in dieses Verzeichnis. Wenn Sie ein von einer kommerziellen Zertifizierungsstelle signiertes SSL-Zertifikat haben, können Sie das Zertifikat und den entsprechenden Schlüssel hier ersetzen, um nicht vertrauenswürdige SSL-Zertifikatswarnungen für Ihre Besucher zu vermeiden:

sudo mv ~//.crt /etc/nginx/ssl
sudo mv ~//.key /etc/nginx/ssl

Ändern Sie die Berechtigungen, damit Benutzer ohne Rootberechtigung nicht auf dieses Verzeichnis zugreifen können:

sudo chmod 700 /etc/nginx/ssl

Überprüfen Sie nun Ihre Nginx-Konfigurationsdatei auf Syntaxfehler:

sudo nginx -t

Wenn keine Syntaxfehler gemeldet werden, können wir den Nginx neu starten:

sudo service nginx restart

Wir können auch unseren uWSGI-Dienst starten:

sudo service uwsgi start

Als letztes müssen wir die Parameterdatei unserer Anwendung kopieren, damit sie beim Bereitstellen von Verbindungen auf Port 443 korrekt gelesen wird. Dieses enthält das Kennwort, das wir für die Verwaltungsschnittstelle konfiguriert haben. Wir müssen es nur in einen neuen Namen kopieren, der Port 443 anstelle von Port 8000 angibt:

cp ~//parameters_8000.py ~//parameters_443.py

Damit sollten Sie in der Lage sein, über den Domainnamen oder die IP-Adresse Ihres Servers auf Ihren Server zuzugreifen. Verwenden Sie "+ https +", wenn Sie sich bei der Verwaltungsoberfläche anmelden möchten.

Fazit

In diesem Handbuch haben wir ein Beispielprojekt für web2py eingerichtet, um die Bereitstellung zu üben. Wir haben uWSGI so konfiguriert, dass es als Schnittstelle zwischen unserer Anwendung und Kundenanforderungen fungiert. Anschließend haben wir Nginx vor uWSGI eingerichtet, um SSL-Verbindungen zu ermöglichen und Client-Anforderungen effizient zu verarbeiten.

Das web2py-Projekt vereinfacht die Entwicklung von Websites und Webanwendungen, indem von Anfang an ein funktionsfähiges Webinterface bereitgestellt wird. Indem Sie die in diesem Artikel beschriebene allgemeine Toolkette nutzen, können Sie die von Ihnen erstellten Anwendungen problemlos von einem einzelnen Server aus bereitstellen.