Servieren von Kolbenanwendungen mit Gunicorn und Nginx unter CentOS 7

Einführung

In diesem Handbuch richten wir eine einfache Python-Anwendung mit dem Flask-Mikro-Framework unter CentOS 7 ein. Der Großteil dieses Artikels befasst sich mit der Einrichtung des Gunicorn-Anwendungsservers zum Starten der Anwendung und von Nginx als Front-End-Reverse-Proxy.

Voraussetzungen

Bevor Sie mit diesem Handbuch beginnen, sollte auf Ihrem Server ein Benutzer ohne Rootberechtigung konfiguriert sein. Dieser Benutzer muss über die Berechtigungen vonsudoverfügen, damit er Verwaltungsfunktionen ausführen kann. Befolgen Sie unsereinitial server setup guide, um zu erfahren, wie Sie dies einrichten.

Um mehr über die WSGI-Spezifikation zu erfahren, die unser Anwendungsserver für die Kommunikation mit unserer Flask-App verwendet, können Sie den verknüpften Abschnitt vonthis guide lesen. Das Verständnis dieser Konzepte erleichtert das Befolgen dieser Anleitung.

Wenn Sie bereit sind fortzufahren, lesen Sie weiter.

Installieren Sie die Komponenten aus den CentOS- und EPEL-Repositorys

Unser erster Schritt wird sein, alle Teile, die wir brauchen, aus den Repositories zu installieren. Wir müssen das EPEL-Repository hinzufügen, das einige zusätzliche Pakete enthält, um einige der benötigten Komponenten zu installieren.

Sie können das EPEL-Repo aktivieren, indem Sie Folgendes eingeben:

sudo yum install epel-release

Sobald der Zugriff auf das EPEL-Repository auf unserem System konfiguriert ist, können wir mit der Installation der benötigten Pakete beginnen. Wir werden pip, den Python-Paketmanager, installieren, um unsere Python-Komponenten zu installieren und zu verwalten. Wir werden auch einen Compiler und die von Gunicorn benötigten Python-Entwicklungsdateien bekommen. Wir werden jetzt auch Nginx installieren.

Sie können alle diese Komponenten installieren, indem Sie Folgendes eingeben:

sudo yum install python-pip python-devel gcc nginx

Erstellen Sie eine virtuelle 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 Paketsvirtualenv mitpip:

sudo pip install virtualenv

Jetzt können wir ein übergeordnetes Verzeichnis für unser Flask-Projekt erstellen. Wechseln Sie in das Verzeichnis, nachdem Sie es erstellt haben:

mkdir ~/myproject
cd ~/myproject

Wir können eine virtuelle Umgebung zum Speichern der Python-Anforderungen unseres Flask-Projekts erstellen, indem Sie Folgendes eingeben:

virtualenv myprojectenv

Dadurch wird eine lokale Kopie von Python undpip in einem Verzeichnis namensmyprojectenv in Ihrem Projektverzeichnis installiert.

Bevor wir Anwendungen in der virtuellen Umgebung installieren, müssen wir sie aktivieren. Sie können dies tun, indem Sie Folgendes eingeben:

source myprojectenv/bin/activate

Ihre Eingabeaufforderung ändert sich und zeigt an, dass Sie jetzt in der virtuellen Umgebung arbeiten. Es wird ungefähr so ​​aussehen wie(myprojectenv)user@host:~/myproject$.

Einrichten einer Kolbenanwendung

Jetzt, da Sie sich in Ihrer virtuellen Umgebung befinden, können wir Flask und Gunicorn installieren und mit dem Entwerfen unserer Anwendung beginnen:

Installieren Sie Flasche und Gunicorn

Wir können die lokale Instanz vonpip verwenden, um Flask und Gunicorn zu installieren. Geben Sie die folgenden Befehle ein, um diese beiden Komponenten abzurufen:

pip install gunicorn flask

Erstellen Sie eine Beispiel-App

Nachdem wir Flask zur Verfügung haben, können wir eine einfache Anwendung erstellen. Der Kolben ist ein Mikrorahmen. 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, die wirmyproject.py nennen:

nano ~/myproject/myproject.py

In dieser Datei platzieren wir unseren Anwendungscode. Grundsätzlich müssen wir flask importieren und ein Flask-Objekt instanziieren. Hiermit können wir die Funktionen definieren, die ausgeführt werden sollen, wenn eine bestimmte Route angefordert wird. Wir rufen unsere Flask-Anwendung im Codeapplication auf, um die Beispiele zu replizieren, die Sie in der WSGI-Spezifikation finden:

from flask import Flask
application = Flask(__name__)

@application.route("/")
def hello():
    return "

Hello There!

" if __name__ == "__main__": application.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.

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

python myproject.py

Besuchen Sie den Domainnamen oder die IP-Adresse Ihres Servers, gefolgt von der in der Terminalausgabe angegebenen Portnummer (höchstwahrscheinlich:5000) in Ihrem Webbrowser. Sie sollten so etwas sehen:

Flask sample app

Wenn Sie fertig sind, drücken Sie einige Male STRG-C im Terminalfenster, um den Flask-Entwicklungsserver zu stoppen.

Erstellen Sie den WSGI-Einstiegspunkt

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.

Wir werden die Dateiwsgi.py aufrufen:

nano ~/myproject/wsgi.py

Die Datei ist unglaublich einfach. Wir können einfach die Flask-Instanz aus unserer Anwendung importieren und dann ausführen:

from myproject import application

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

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

Testen von Gunicorns Fähigkeit, dem Projekt zu dienen

Bevor wir weitermachen, sollten wir überprüfen, ob Gunicorn richtig kann.

Wir können dies tun, indem wir einfach den Namen unseres Einstiegspunkts übergeben. Wir geben auch die Schnittstelle und den Port an, an den die Bindung erfolgen soll, damit sie auf einer öffentlich verfügbaren Schnittstelle gestartet werden:

cd ~/myproject
gunicorn --bind 0.0.0.0:8000 wsgi

Wenn Sie den Domainnamen oder die IP-Adresse Ihres Servers mit:8000 am Ende Ihres Webbrowsers aufrufen, sollte eine Seite angezeigt werden, die folgendermaßen aussieht:

Flask sample app

Wenn Sie die ordnungsgemäße Funktion bestätigt haben, drücken Sie STRG-C in Ihrem Terminalfenster.

Wir sind jetzt mit unserer virtuellen Umgebung fertig und können sie deaktivieren:

deactivate

Alle Vorgänge werden jetzt in der Python-Umgebung des Systems ausgeführt.

Erstellen Sie eine Systemd Unit-Datei

Das nächste Teil, um das wir uns kümmern müssen, ist die Systemd-Service-Unit-Datei. Durch das Erstellen einer Systemd-Unit-Datei kann das CentOS-Init-System Gunicorn automatisch starten und unsere Flask-Anwendung bei jedem Start des Servers bedienen.

Erstellen Sie eine Datei mit der Endung.service im Verzeichnis/etc/systemd/system, um zu beginnen:

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

Im Inneren beginnen wir mit einem Abschnitt[Unit], in dem Metadaten und Abhängigkeiten angegeben werden. Wir werden hier eine Beschreibung unseres Dienstes einfügen und das init-System anweisen, diese erst zu starten, nachdem das Netzwerkziel erreicht wurde:

[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

Als Nächstes öffnen wir den Abschnitt[Service]. Wir geben den Benutzer und die Gruppe an, unter denen der Prozess ausgeführt werden soll. Wir geben unserem regulären Benutzerkonto den Besitz des Prozesses, da ihm alle relevanten Dateien gehören. Wir geben der Nginx-Benutzergruppe den Besitz, damit sie problemlos mit den Gunicorn-Prozessen kommunizieren kann.

Anschließend ordnen wir das Arbeitsverzeichnis zu und legen die UmgebungsvariablePATHfest, damit das Init-System weiß, wo sich die ausführbaren Dateien für den Prozess befinden (innerhalb unserer virtuellen Umgebung). Anschließend geben wir den Befehl zum Starten des Dienstes an. Systemd erfordert, dass wir den vollständigen Pfad zur ausführbaren Datei von Gunicorn angeben, die in unserer virtuellen Umgebung installiert ist.

Wir werden es anweisen, 3 Worker-Prozesse zu starten (passen Sie dies nach Bedarf an). Wir werden es auch anweisen, eine Unix-Socket-Datei in unserem Projektverzeichnis mit dem Namenmyproject.sock zu erstellen und an diese zu binden. 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. Schließlich müssen wir den WSGI-Einstiegspunkt-Dateinamen übergeben:

[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

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

Das letzte Stück, das wir der Datei hinzufügen müssen, ist ein Abschnitt[Install]. Dies teilt Systemd mit, mit was dieser Dienst verknüpft werden soll, wenn er beim Start gestartet werden kann. Wir möchten, dass dieser Dienst gestartet wird, wenn das reguläre Mehrbenutzersystem ausgeführt wird:

[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

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

[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

Konfigurieren von Nginx für Proxy-Anforderungen

Unser Gunicorn-Anwendungsserver sollte nun betriebsbereit sein und auf Anforderungen in der Socket-Datei im Projektverzeichnis warten. Wir müssen Nginx so konfigurieren, dass Webanforderungen an diesen Socket weitergeleitet werden, indem wir einige kleine Ergänzungen zu seiner Konfigurationsdatei vornehmen.

Öffnen Sie zunächst die Standardkonfigurationsdatei von Nginx:

sudo nano /etc/nginx/nginx.conf

Öffnen Sie einen Serverblock direkt über dem anderenserver {}-Block, der sich bereits in der Datei befindet:

http {
    . . .

    include /etc/nginx/conf.d/*.conf;

    server {
    }

    server {
        listen 80 default_server;

        . . .

Wir werden die gesamte Konfiguration für unsere Kolbenanwendung in diesen neuen Block einfügen. Zunächst legen wir fest, dass dieser Block den Standard-Port 80 überwacht und auf den Domain-Namen oder die IP-Adresse unseres Servers reagiert:

server {
    listen 80;
    server_name server_domain_or_IP;
}

Das einzige andere, was wir hinzufügen müssen, ist ein Standortblock, der zu jeder Anfrage passt. In diesem Block werden einige standardmäßige HTTP-Header für Proxys festgelegt, damit Gunicorn Informationen über die Remoteclientverbindung erhalten kann. Wir leiten den Datenverkehr dann an den Socket weiter, den wir in unserer Systemd-Unit-Datei angegeben haben:

server {
    listen 80;
    server_name server_domain_or_IP;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://unix:/home/user/myproject/myproject.sock;
    }
}

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

Der Benutzer vonnginxmuss Zugriff auf unser Anwendungsverzeichnis haben, um dort auf die Socket-Datei zugreifen zu können. Standardmäßig sperrt CentOS das Home-Verzeichnis jedes Benutzers sehr restriktiv, sodass wir den Benutzernginxzur Benutzergruppe hinzufügen, damit wir die Mindestberechtigungen öffnen können, die für die Gewährung des Zugriffs erforderlich sind.

Mit dem folgenden Befehl können Sie den Benutzernginxzu Ihrer Benutzergruppe hinzufügen. Ersetzen Sie dieuser im Befehl durch Ihren eigenen Benutzernamen:

sudo usermod -a -G user nginx

Jetzt können wir unserer Benutzergruppe Ausführungsberechtigungen für unser Ausgangsverzeichnis erteilen. Auf diese Weise kann der Nginx-Prozess Inhalte in folgenden Bereichen eingeben und darauf zugreifen:

chmod 710 /home/user

Mit den eingerichteten Berechtigungen können wir unsere Nginx-Konfigurationsdatei auf Syntaxfehler testen:

sudo nginx -t

Wenn dies ohne Angabe von Problemen zurückgegeben wird, können wir den Nginx-Prozess starten und aktivieren, sodass er automatisch beim Booten gestartet wird:

sudo systemctl start nginx
sudo systemctl enable nginx

Sie sollten nun in der Lage sein, den Domainnamen oder die IP-Adresse Ihres Servers in Ihrem Webbrowser aufzurufen und Ihre Anwendung anzuzeigen:

Flask sample app

Fazit

In diesem Handbuch haben wir eine einfache Flask-Anwendung in einer virtuellen Python-Umgebung erstellt. Wir erstellen einen WSGI-Einstiegspunkt, damit jeder WSGI-fähige Anwendungsserver mit ihm kommunizieren kann, und konfigurieren dann den Gunicorn-App-Server so, dass er diese Funktion bereitstellt. Anschließend haben wir eine Systemd-Unit-Datei erstellt, um den Anwendungsserver beim Booten automatisch zu starten. Wir haben einen Nginx-Serverblock erstellt, der den Webclient-Datenverkehr an den Anwendungsserver weiterleitet und externe Anforderungen weiterleitet.

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.