Wie man Django mit Postgres, Nginx und Gunicorn unter Debian 9 einrichtet

Einführung

Django ist ein leistungsstarkes Webframework, mit dem Sie Ihre Python-Anwendung oder -Website auf den Markt bringen können. Django enthält einen vereinfachten Entwicklungsserver zum Testen Ihres Codes vor Ort, aber für alles, was auch nur geringfügig mit der Produktion zu tun hat, ist ein sicherer und leistungsfähigerer Webserver erforderlich.

In diesem Handbuch werden wir zeigen, wie einige Komponenten auf Debian 9 installiert und konfiguriert werden, um Django-Anwendungen zu unterstützen und zu bedienen. Wir werden eine PostgreSQL-Datenbank einrichten, anstatt die Standard-SQLite-Datenbank zu verwenden. Wir werden den Gunicorn-Anwendungsserver so konfigurieren, dass er mit unseren Anwendungen kommuniziert. Wir werden dann Nginx so einrichten, dass es den Proxy für Gunicorn umkehrt, wodurch wir Zugriff auf seine Sicherheits- und Leistungsmerkmale erhalten, um unsere Apps bereitzustellen.

Voraussetzungen

Um dieses Handbuch zu vervollständigen, sollten Sie eine neue Debian 9-Serverinstanz mit einer grundlegenden Firewall und einen Nicht-Root-Benutzer mit konfigurierten "+ sudo +" - Berechtigungen haben. Informationen zum Einrichten finden Sie in unserem initial server setup guide.

Wir werden Django in einer virtuellen Umgebung installieren. Durch die Installation von Django in einer für Ihr Projekt spezifischen Umgebung können Ihre Projekte und deren Anforderungen separat behandelt werden.

Sobald wir unsere Datenbank und Anwendung zum Laufen gebracht haben, werden wir den Gunicorn-Anwendungsserver installieren und konfigurieren. Dies dient als Schnittstelle zu unserer Anwendung und übersetzt Client-Anforderungen von HTTP in Python-Aufrufe, die von unserer Anwendung verarbeitet werden können. Wir werden dann Nginx vor Gunicorn einrichten, um die Vorteile seiner hochleistungsfähigen Verbindungsbehandlungsmechanismen und seiner einfach zu implementierenden Sicherheitsfunktionen zu nutzen.

Lass uns anfangen.

Schritt 1 - Installieren der Pakete aus den Debian-Repositories

Zu Beginn des Vorgangs werden wir alle benötigten Elemente aus den Debian-Repositories herunterladen und installieren. Wir werden den Python-Paketmanager + pip + verwenden, um zusätzliche Komponenten etwas später zu installieren.

Wir müssen den lokalen "+ apt +" - Paketindex aktualisieren und dann die Pakete herunterladen und installieren. Welche Pakete wir installieren, hängt davon ab, welche Python-Version Ihr Projekt verwenden wird.

Wenn Sie Django mit * Python 3 * verwenden, geben Sie Folgendes ein:

sudo apt update
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl

Django 1.11 ist die letzte Version von Django, die Python 2 unterstützt. Wenn Sie neue Projekte starten, wird dringend empfohlen, Python 3 zu wählen. Wenn Sie weiterhin * Python 2 * verwenden müssen, geben Sie Folgendes ein:

sudo apt update
sudo apt install python-pip python-dev libpq-dev postgresql postgresql-contrib nginx curl

Dadurch werden + pip +, die Python-Entwicklungsdateien, die für die spätere Erstellung von Gunicorn benötigt werden, das Postgres-Datenbanksystem und die Bibliotheken, die für die Interaktion erforderlich sind, sowie der Nginx-Webserver installiert.

Schritt 2 - Erstellen der PostgreSQL-Datenbank und des Benutzers

Wir werden sofort loslegen und eine Datenbank und einen Datenbankbenutzer für unsere Django-Anwendung erstellen.

Standardmäßig verwendet Postgres ein Authentifizierungsschema mit der Bezeichnung "Peer-Authentifizierung" für lokale Verbindungen. Grundsätzlich bedeutet dies, dass sich der Benutzer ohne weitere Authentifizierung anmelden kann, wenn der Benutzername des Betriebssystems des Benutzers mit einem gültigen Postgres-Benutzernamen übereinstimmt.

Während der Postgres-Installation wurde ein Betriebssystembenutzer mit dem Namen "+ postgres " erstellt, der dem administrativen Benutzer " postgres " PostgreSQL entspricht. Wir müssen diesen Benutzer verwenden, um administrative Aufgaben auszuführen. Wir können sudo verwenden und den Benutzernamen mit der Option " -u +" übergeben.

Melden Sie sich bei einer interaktiven Postgres-Sitzung an, indem Sie Folgendes eingeben:

sudo -u postgres psql

Sie erhalten eine PostgreSQL-Eingabeaufforderung, in der wir unsere Anforderungen festlegen können.

Erstellen Sie zunächst eine Datenbank für Ihr Projekt:

CREATE DATABASE ;

Erstellen Sie als Nächstes einen Datenbankbenutzer für unser Projekt. Stellen Sie sicher, dass Sie ein sicheres Passwort wählen:

CREATE USER  WITH PASSWORD '';

Anschließend ändern wir einige der Verbindungsparameter für den gerade erstellten Benutzer. Dies beschleunigt die Datenbankoperationen, sodass nicht bei jedem Verbindungsaufbau die richtigen Werte abgefragt und eingestellt werden müssen.

Wir setzen die Standardkodierung auf "+ UTF-8 ", was Django erwartet. Wir setzen außerdem das Standard-Transaktionsisolationsschema auf "read commit", wodurch Lesevorgänge für nicht festgeschriebene Transaktionen blockiert werden. Zuletzt stellen wir die Zeitzone ein. Standardmäßig verwenden Ihre Django-Projekte " UTC". Dies sind alles Empfehlungen von das Django-Projekt selbst:

ALTER ROLE  SET client_encoding TO 'utf8';
ALTER ROLE  SET default_transaction_isolation TO 'read committed';
ALTER ROLE  SET timezone TO 'UTC';

Jetzt können wir unserem neuen Benutzer Zugriff auf die Verwaltung unserer neuen Datenbank gewähren:

GRANT ALL PRIVILEGES ON DATABASE  TO ;

Wenn Sie fertig sind, beenden Sie die PostgreSQL-Eingabeaufforderung, indem Sie Folgendes eingeben:

\q

Postgres ist nun so eingerichtet, dass Django eine Verbindung zu seinen Datenbankinformationen herstellen und diese verwalten kann.

Schritt 3 - Erstellen einer virtuellen Python-Umgebung für Ihr Projekt

Nachdem wir unsere Datenbank haben, können wir damit beginnen, den Rest unserer Projektanforderungen vorzubereiten. Wir werden unsere Python-Anforderungen in einer virtuellen Umgebung installieren, um die Verwaltung zu vereinfachen.

Dazu benötigen wir zunächst den Befehl + virtualenv +. Wir können dies mit + pip + installieren.

Wenn Sie * Python 3 * verwenden, aktualisieren Sie + pip + und installieren Sie das Paket, indem Sie Folgendes eingeben:

sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv

Wenn Sie * Python 2 * verwenden, aktualisieren Sie + pip + und installieren Sie das Paket, indem Sie Folgendes eingeben:

sudo -H pip install --upgrade pip
sudo -H pip install virtualenv

Wenn "+ virtualenv +" installiert ist, können wir mit der Gestaltung unseres Projekts beginnen. Erstellen Sie ein Verzeichnis und verschieben Sie es in ein Verzeichnis, in dem wir unsere Projektdateien aufbewahren können:

mkdir ~/
cd ~/

Erstellen Sie im Projektverzeichnis eine virtuelle Python-Umgebung, indem Sie Folgendes eingeben:

virtualenv

Dadurch wird ein Verzeichnis mit dem Namen "" in Ihrem "" - Verzeichnis erstellt. Im Inneren wird eine lokale Version von Python und eine lokale Version von + pip + installiert. Damit können wir eine isolierte Python-Umgebung für unser Projekt installieren und konfigurieren.

Bevor wir die Python-Anforderungen unseres Projekts installieren, müssen wir die virtuelle Umgebung aktivieren. Sie können dies tun, indem Sie Folgendes eingeben:

source /bin/activate

Ihre Eingabeaufforderung sollte sich ändern, um anzuzeigen, dass Sie jetzt in einer virtuellen Python-Umgebung arbeiten. Es sieht ungefähr so ​​aus: + () @: ~ / $ +.

Installieren Sie bei aktivierter virtueller Umgebung Django, Gunicorn und den PostgreSQL-Adapter + psycopg2 + mit der lokalen Instanz von + pip +:

pip install django gunicorn psycopg2-binary

Sie sollten nun über die gesamte Software verfügen, die zum Starten eines Django-Projekts erforderlich ist.

Schritt 4 - Erstellen und Konfigurieren eines neuen Django-Projekts

Mit unseren installierten Python-Komponenten können wir die eigentlichen Django-Projektdateien erstellen.

Django-Projekt erstellen

Da wir bereits ein Projektverzeichnis haben, werden wir Django anweisen, die Dateien hier zu installieren. Es wird ein Verzeichnis der zweiten Ebene mit dem tatsächlichen Code erstellt, der normal ist, und ein Verwaltungsskript wird in dieses Verzeichnis eingefügt. Der Schlüssel dazu ist, dass wir das Verzeichnis explizit definieren, anstatt Django zu erlauben, Entscheidungen in Bezug auf unser aktuelles Verzeichnis zu treffen:

django-admin.py startproject  ~/

Zu diesem Zeitpunkt sollte Ihr Projektverzeichnis (in unserem Fall "+ ~ / +") den folgenden Inhalt haben:

  • + ~ / myprojectdir / manage.py +: Ein Django-Projektverwaltungsskript.

  • + ~ / myprojectdir / myproject / +: Das Django-Projektpaket. Dies sollte die Dateien "+ init . Py ", " settings.py ", " urls.py " und " wsgi.py +" enthalten.

  • + ~ / myprojectdir / myprojectenv / +: Das zuvor erstellte Verzeichnis der virtuellen Umgebung.

Anpassen der Projekteinstellungen

Das erste, was wir mit unseren neu erstellten Projektdateien tun sollten, ist, die Einstellungen anzupassen. Öffnen Sie die Einstellungsdatei in Ihrem Texteditor:

nano ~///settings.py

Suchen Sie zunächst die Direktive + ALLOWED_HOSTS +. Hiermit wird eine Liste der Serveradressen definiert, oder es können Domänennamen verwendet werden, um eine Verbindung zur Django-Instanz herzustellen. Alle eingehenden Anforderungen mit einem * Host * -Header, der nicht in dieser Liste enthalten ist, lösen eine Ausnahme aus. Django erfordert, dass Sie dies einstellen, um eine bestimmte Sicherheitslücke zu vermeiden.

Listen Sie in den eckigen Klammern die IP-Adressen oder Domänennamen auf, die Ihrem Django-Server zugeordnet sind. Jeder Artikel sollte in Anführungszeichen mit durch Komma getrennten Einträgen aufgeführt werden. Wenn Sie Anfragen für eine gesamte Domain und Subdomains wünschen, stellen Sie einen Punkt vor den Beginn des Eintrags. Im folgenden Snippet sind einige Beispiele auskommentiert, um Folgendes zu demonstrieren:

~ / myprojectdir / myproject / settings.py

. . .
# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['', '', , 'localhost']

Suchen Sie als Nächstes den Abschnitt, der den Datenbankzugriff konfiguriert. Es beginnt mit + DATABASES +. Die Konfiguration in der Datei bezieht sich auf eine SQLite-Datenbank. Wir haben bereits eine PostgreSQL-Datenbank für unser Projekt erstellt, daher müssen wir die Einstellungen anpassen.

Ändern Sie die Einstellungen mit Ihren PostgreSQL-Datenbankinformationen. Wir weisen Django an, den Adapter "+ psycopg2 " zu verwenden, den wir mit " pip " installiert haben. Wir müssen den Datenbanknamen, den Datenbankbenutzernamen und das Kennwort des Datenbankbenutzers angeben und dann angeben, dass sich die Datenbank auf dem lokalen Computer befindet. Sie können die Einstellung " PORT +" als leere Zeichenfolge belassen:

~ / myprojectdir / myproject / settings.py

. . .

DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.',
       'NAME': '',
       'USER': '',
       'PASSWORD': '',
       'HOST': 'localhost',
       'PORT': '',
   }
}

. . .

Bewegen Sie sich als Nächstes zum Ende der Datei und fügen Sie eine Einstellung hinzu, die angibt, wo die statischen Dateien abgelegt werden sollen. Dies ist erforderlich, damit Nginx Anfragen für diese Artikel bearbeiten kann. Die folgende Zeile weist Django an, sie in einem Verzeichnis mit dem Namen "+ static +" im Basisprojektverzeichnis abzulegen:

~ / myprojectdir / myproject / settings.py

. . .

STATIC_URL = '/static/'

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

Fertigstellen der anfänglichen Projekteinrichtung

Jetzt können wir das anfängliche Datenbankschema mithilfe des Verwaltungsskripts in unsere PostgreSQL-Datenbank migrieren:

~//manage.py makemigrations
~//manage.py migrate

Erstellen Sie einen Administrator für das Projekt, indem Sie Folgendes eingeben:

~//manage.py createsuperuser

Sie müssen einen Benutzernamen auswählen, eine E-Mail-Adresse angeben und ein Passwort auswählen und bestätigen.

Wir können den gesamten statischen Inhalt in dem von uns konfigurierten Verzeichnis speichern, indem wir Folgendes eingeben:

~//manage.py collectstatic

Sie müssen den Vorgang bestätigen. Die statischen Dateien werden dann in einem Verzeichnis mit dem Namen "+ static +" in Ihrem Projektverzeichnis abgelegt.

Wenn Sie die anfängliche Anleitung zur Serverkonfiguration befolgt haben, sollte Ihr Server durch eine UFW-Firewall geschützt sein. Zum Testen des Entwicklungsservers müssen wir den Zugriff auf den von uns verwendeten Port zulassen.

Erstellen Sie eine Ausnahme für Port 8000, indem Sie Folgendes eingeben:

sudo ufw allow 8000

Zum Schluss können Sie Ihr Projekt testen, indem Sie den Django-Entwicklungsserver mit folgendem Befehl starten:

~//manage.py runserver 0.0.0.0:8000

Besuchen Sie in Ihrem Webbrowser den Domainnamen oder die IP-Adresse Ihres Servers, gefolgt von "+: 8000 +":

http://:8000

Sie sollten die Standard-Django-Indexseite sehen:

Wenn Sie "+ / admin " an das Ende der URL in der Adressleiste anhängen, werden Sie aufgefordert, den Administrator-Benutzernamen und das Kennwort einzugeben, die Sie mit dem Befehl " createduperuser" erstellt haben:

Nach der Authentifizierung können Sie auf die standardmäßige Django-Administrationsoberfläche zugreifen:

Wenn Sie mit dem Durchsuchen fertig sind, drücken Sie im Terminalfenster * STRG-C *, um den Entwicklungsserver herunterzufahren.

Testen von Gunicorns Fähigkeit, dem Projekt zu dienen

Das Letzte, was wir tun möchten, bevor wir unsere virtuelle Umgebung verlassen, ist Gunicorn zu testen, um sicherzustellen, dass es die Anwendung bedienen kann. Wir können dies tun, indem wir unser Projektverzeichnis eingeben und mit "+ gunicorn +" das WSGI-Modul des Projekts laden:

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

Dadurch wird Gunicorn auf derselben Oberfläche gestartet, auf der der Django-Entwicklungsserver ausgeführt wurde. Sie können die App erneut testen.

Wir haben Gunicorn ein Modul übergeben, indem wir den relativen Verzeichnispfad zu Djangos "+ wsgi.py " - Datei, die der Einstiegspunkt für unsere Anwendung ist, mithilfe der Modulsyntax von Python angegeben haben. In dieser Datei ist eine Funktion mit dem Namen " application +" definiert, die für die Kommunikation mit der Anwendung verwendet wird. Weitere Informationen zur WSGI-Spezifikation 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 [hier].

Wenn Sie mit dem Testen fertig sind, drücken Sie im Terminalfenster * STRG-C *, um Gunicorn zu stoppen.

Wir sind jetzt mit der Konfiguration unserer Django-Anwendung fertig. Wir können unsere virtuelle Umgebung verlassen, indem wir Folgendes eingeben:

deactivate

Die Anzeige für die virtuelle Umgebung in Ihrer Eingabeaufforderung wird entfernt.

Schritt 5 - Systemd Socket und Service Files für Gunicorn erstellen

Wir haben getestet, dass Gunicorn mit unserer Django-Anwendung interagieren kann, aber wir sollten eine robustere Methode zum Starten und Stoppen des Anwendungsservers implementieren. Zu diesem Zweck erstellen wir System-Service- und Socket-Dateien.

Der Gunicorn-Socket wird beim Booten erstellt und wartet auf Verbindungen. Wenn eine Verbindung hergestellt wird, startet systemd automatisch den Gunicorn-Prozess, um die Verbindung herzustellen.

Beginnen Sie mit dem Erstellen und Öffnen einer systemd-Socket-Datei für Gunicorn mit den Rechten "+ sudo +":

sudo nano /etc/systemd/system/gunicorn.socket

Im Inneren werden wir einen Abschnitt "+ [Unit] " erstellen, um den Socket zu beschreiben, einen Abschnitt " [Socket] ", um die Position des Sockets zu definieren, und einen Abschnitt " [Install] +", um sicherzustellen, dass der Socket ist zum richtigen Zeitpunkt erstellt:

/etc/systemd/system/gunicorn.socket

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

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

Als nächstes erstellen und öffnen Sie eine systemd-Servicedatei für Gunicorn mit den Privilegien "+ sudo +" in Ihrem Texteditor. Der Dienstdateiname sollte mit Ausnahme der Erweiterung mit dem Socketdateinamen übereinstimmen:

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

Beginnen Sie mit dem 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. Da unser Service auf dem Socket aus der Socket-Datei beruht, müssen wir eine Direktive " Requires +" einfügen, um diese Beziehung anzuzeigen:

/etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

Als nächstes öffnen wir den Abschnitt "+ [Service] ". Wir geben den Benutzer und die Gruppe an, unter denen die Ausführung erfolgen soll. Wir geben unserem regulären Benutzerkonto den Besitz des Prozesses, da ihm alle relevanten Dateien gehören. Wir geben der Gruppe " www-data" den Besitz einer Gruppe, damit Nginx problemlos mit Gunicorn kommunizieren kann.

Anschließend ordnen wir das Arbeitsverzeichnis zu und geben den Befehl zum Starten des Dienstes an. In diesem Fall müssen wir den vollständigen Pfad zur ausführbaren Datei von Gunicorn angeben, die in unserer virtuellen Umgebung installiert ist. Wir binden den Prozess an den Unix-Socket, den wir im Verzeichnis "+ / run " erstellt haben, damit der Prozess mit Nginx kommunizieren kann. Wir protokollieren alle Daten in der Standardausgabe, damit der Prozess " journald +" die Gunicorn-Protokolle erfassen kann. Wir können hier auch optionale Gunicorn-Anpassungen festlegen. In diesem Fall haben wir beispielsweise drei Worker-Prozesse angegeben:

/etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=
Group=www-data
WorkingDirectory=/home//
ExecStart=/home////bin/gunicorn \
         --access-logfile - \
         --workers 3 \
         --bind unix:/run/gunicorn.sock \
         .wsgi:application

Schließlich 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/gunicorn.service

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=
Group=www-data
WorkingDirectory=/home//
ExecStart=/home////bin/gunicorn \
         --access-logfile - \
         --workers 3 \
         --bind unix:/run/gunicorn.sock \
         .wsgi:application

[Install]
WantedBy=multi-user.target

Damit ist unsere systemd-Servicedatei vollständig. Speichern und schließen Sie es jetzt.

Jetzt können wir den Gunicorn-Sockel starten und aktivieren. Dadurch wird die Socket-Datei jetzt und beim Booten unter + / run / gunicorn.sock + erstellt. Wenn eine Verbindung zu diesem Socket hergestellt wird, startet systemd automatisch den Dienst "+ gunicorn.service", um dies zu erledigen:

sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket

Wir können bestätigen, dass der Vorgang erfolgreich war, indem wir nach der Socket-Datei suchen.

Schritt 6 - Überprüfen der Gunicorn Socket-Datei

Überprüfen Sie den Status des Prozesses, um festzustellen, ob er gestartet werden konnte:

sudo systemctl status gunicorn.socket

Überprüfen Sie als nächstes, ob die Datei "+ gunicorn.sock " im Verzeichnis " / run +" vorhanden ist:

file /run/gunicorn.sock
Output/run/gunicorn.sock: socket

Wenn der Befehl "+ systemctl status " angibt, dass ein Fehler aufgetreten ist, oder wenn Sie die Datei " gunicorn.sock +" im Verzeichnis nicht finden, bedeutet dies, dass der Gunicorn-Socket nicht ordnungsgemäß erstellt werden konnte. Überprüfen Sie die Protokolle des Gunicorn-Sockets, indem Sie Folgendes eingeben:

sudo journalctl -u gunicorn.socket

Sehen Sie sich die Datei "+ / etc / systemd / system / gunicorn.socket +" noch einmal an, um eventuelle Probleme zu beheben, bevor Sie fortfahren.

Schritt 7 - Testen der Socket-Aktivierung

Wenn Sie nur die Einheit "+ gunicorn.socket" gestartet haben, ist "+ gunicorn.service" derzeit noch nicht aktiv, da die Socket noch keine Verbindungen erhalten hat. Sie können dies überprüfen, indem Sie Folgendes eingeben:

sudo systemctl status gunicorn
Output● gunicorn.service - gunicorn daemon
  Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)

Um den Socket-Aktivierungsmechanismus zu testen, können wir eine Verbindung zum Socket über "+ curl +" senden, indem wir Folgendes eingeben:

curl --unix-socket /run/gunicorn.sock localhost

Sie sollten die HTML-Ausgabe Ihrer Anwendung im Terminal sehen. Dies zeigt an, dass Gunicorn gestartet wurde und Ihre Django-Anwendung bedienen konnte. Sie können überprüfen, ob der Gunicorn-Dienst ausgeführt wird, indem Sie Folgendes eingeben:

sudo systemctl status gunicorn
Output● gunicorn.service - gunicorn daemon
  Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
   since Mon 2018-07-09 20:00:40 UTC; 4s ago
Main PID: 1157 (gunicorn)
   Tasks: 4 (limit: 1153)
  CGroup: /system.slice/gunicorn.service
          ├─1157 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
          ├─1178 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
          ├─1180 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
          └─1181 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application

Jul 09 20:00:40 django1 systemd[1]: Started gunicorn daemon.
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Starting gunicorn 19.9.0
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Listening at: unix:/run/gunicorn.sock (1157)
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Using worker: sync
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1178] [INFO] Booting worker with pid: 1178
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1180] [INFO] Booting worker with pid: 1180
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1181] [INFO] Booting worker with pid: 1181
Jul 09 20:00:41 django1 gunicorn[1157]:  - - [09/Jul/2018:20:00:41 +0000] "GET / HTTP/1.1" 200 16348 "-" "curl/7.58.0"

Wenn die Ausgabe von "+ curl" oder die Ausgabe von "+ systemctl status" anzeigt, dass ein Problem aufgetreten ist, überprüfen Sie die Protokolle auf weitere Details:

sudo journalctl -u gunicorn

Überprüfen Sie Ihre Datei + / etc / systemd / system / gunicorn.service + auf Probleme. Wenn Sie Änderungen an der Datei "+ /etc/systemd/system/gunicorn.service +" vornehmen, laden Sie den Dämon erneut, um die Service-Definition erneut zu lesen, und starten Sie den Gunicorn-Prozess erneut, indem Sie Folgendes eingeben:

sudo systemctl daemon-reload
sudo systemctl restart gunicorn

Stellen Sie sicher, dass Sie die obigen Probleme beheben, bevor Sie fortfahren.

Schritt 8 - Konfigurieren Sie Nginx für den Proxy-Pass für Gunicorn

Nachdem Gunicorn eingerichtet ist, müssen wir Nginx so konfigurieren, dass der Datenverkehr an den Prozess weitergeleitet wird.

Beginnen Sie mit dem Erstellen und Öffnen eines neuen Serverblocks im Verzeichnis "+ sites-available +" von Nginx:

sudo nano /etc/nginx/sites-available/

Öffnen Sie im Inneren einen neuen Serverblock. Wir beginnen mit der Angabe, dass dieser Block den normalen Port 80 überwachen und auf den Domainnamen oder die IP-Adresse unseres Servers reagieren soll:

/ etc / nginx / sites-available / myproject

server {
   listen 80;
   server_name ;
}

Als Nächstes werden wir Nginx anweisen, Probleme beim Auffinden eines Favicons zu ignorieren. Wir werden ihm auch mitteilen, wo sich die statischen Assets befinden, die wir in unserem + ~ // static + - Verzeichnis gesammelt haben. Alle diese Dateien haben das Standard-URI-Präfix "/ static", sodass wir einen Standortblock erstellen können, der diesen Anforderungen entspricht:

/ etc / nginx / sites-available / myproject

server {
   listen 80;
   server_name ;

   location = /favicon.ico { access_log off; log_not_found off; }
   location /static/ {
       root /home//;
   }
}

Schließlich erstellen wir einen "+ location / {} " - Block, der allen anderen Anforderungen entspricht. Innerhalb dieses Speicherorts fügen wir die Standarddatei " proxy_params +" hinzu, die in der Nginx-Installation enthalten ist. Anschließend leiten wir den Datenverkehr direkt an den Gunicorn-Socket weiter:

/ etc / nginx / sites-available / myproject

server {
   listen 80;
   server_name ;

   location = /favicon.ico { access_log off; log_not_found off; }
   location /static/ {
       root /home//;
   }

   location / {
       include proxy_params;
       proxy_pass http://unix:/run/gunicorn.sock;
   }
}

Speichern und schließen Sie die Datei, wenn Sie fertig sind. Jetzt können wir die Datei aktivieren, indem wir sie mit dem Verzeichnis + sites-enabled + verknüpfen:

sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled

Testen Sie Ihre Nginx-Konfiguration auf Syntaxfehler, indem Sie Folgendes eingeben:

sudo nginx -t

Wenn keine Fehler gemeldet werden, starten Sie Nginx neu, indem Sie Folgendes eingeben:

sudo systemctl restart nginx

Schließlich müssen wir unsere Firewall für den normalen Datenverkehr auf Port 80 öffnen. Da wir keinen Zugriff mehr auf den Entwicklungsserver benötigen, können wir die Regel zum Öffnen von Port 8000 auch entfernen:

sudo ufw delete allow 8000
sudo ufw allow 'Nginx Full'

Sie sollten nun in der Lage sein, die Domain oder IP-Adresse Ihres Servers aufzurufen, um Ihre Anwendung anzuzeigen.

Fehlerbehebung bei Nginx und Gunicorn

Wenn in diesem letzten Schritt Ihre Anwendung nicht angezeigt wird, müssen Sie eine Fehlerbehebung für Ihre Installation durchführen.

Nginx zeigt die Standardseite anstelle der Django-Anwendung an

Wenn Nginx die Standardseite anzeigt, anstatt auf Ihre Anwendung zu verweisen, bedeutet dies normalerweise, dass Sie in der Datei "+ / etc / nginx / sites-available / " das Zeichen " Servername +" anpassen müssen, um auf die IP-Adresse Ihres Servers zu verweisen Domain Name.

Nginx verwendet "+ Servername ", um zu bestimmen, welcher Serverblock zur Beantwortung von Anfragen verwendet werden soll. Wenn Sie die Standard-Nginx-Seite sehen, ist dies ein Zeichen dafür, dass Nginx die Anfrage nicht explizit einem Serverblock zuordnen konnte. Daher wird auf den Standardblock zurückgegriffen, der in ` / etc / nginx / sites-available / definiert ist. Standard + `.

Das "+ Servername +" im Serverblock Ihres Projekts muss genauer sein als das im Standardserverblock, der ausgewählt werden soll.

Nginx zeigt einen 502 Bad Gateway Error anstelle der Django-Anwendung an

Ein 502-Fehler weist darauf hin, dass Nginx die Anforderung nicht erfolgreich übermitteln kann. Eine Vielzahl von Konfigurationsproblemen äußert sich in einem 502-Fehler. Für eine ordnungsgemäße Fehlerbehebung sind daher weitere Informationen erforderlich.

Weitere Informationen finden Sie in den Fehlerprotokollen von Nginx. In der Regel erfahren Sie, welche Bedingungen während des Proxy-Vorgangs zu Problemen geführt haben. Folgen Sie den Nginx-Fehlerprotokollen, indem Sie Folgendes eingeben:

sudo tail -F /var/log/nginx/error.log

Stellen Sie jetzt eine weitere Anfrage in Ihrem Browser, um einen neuen Fehler zu generieren (versuchen Sie, die Seite zu aktualisieren). Sie sollten eine neue Fehlermeldung im Protokoll sehen. Wenn Sie sich die Meldung ansehen, kann dies Ihnen helfen, das Problem einzugrenzen.

Möglicherweise wird die folgende Meldung angezeigt:

  • connect () to unix: /run/gunicorn.sock fehlgeschlagen (2: Keine solche Datei oder Verzeichnis) *

Dies zeigt an, dass Nginx die Datei "+ gunicorn.sock " am angegebenen Speicherort nicht finden konnte. Sie sollten den in der Datei " / etc / nginx / sites-available / myproject " definierten Speicherort von " proxy_pass " mit dem tatsächlichen Speicherort der Datei " gunicorn.sock " vergleichen, die von der Systemeinheit " gunicorn.socket +" generiert wurde.

Wenn Sie im Verzeichnis "+ / run " keine " gunicorn.sock +" -Datei finden, bedeutet dies im Allgemeinen, dass die systemd-Socket-Datei diese nicht erstellen konnte. Gehen Sie zurück zu dem Link: # Prüfung auf die Gunicorn-Socket-Datei [Abschnitt über die Prüfung auf die Gunicorn-Socket-Datei], um die Schritte zur Fehlerbehebung für Gunicorn zu durchlaufen.

  • connect () to unix: /run/gunicorn.sock fehlgeschlagen (13: Erlaubnis verweigert) *

Dies weist darauf hin, dass Nginx aufgrund von Berechtigungsproblemen keine Verbindung zum Gunicorn-Socket herstellen konnte. Dies kann passieren, wenn die Prozedur unter Verwendung des Root-Benutzers anstelle eines "+ sudo +" - Benutzers ausgeführt wird. Während systemd die Gunicorn-Socket-Datei erstellen kann, kann Nginx nicht darauf zugreifen.

Dies kann vorkommen, wenn an einer beliebigen Stelle zwischen dem Stammverzeichnis (+ / +) der Datei + gunicorn.sock + eingeschränkte Berechtigungen bestehen. Sie können die Berechtigungen und Besitzwerte der Socket-Datei und der übergeordneten Verzeichnisse anzeigen, indem Sie den absoluten Pfad zu unserer Socket-Datei an den Befehl "+ namei +" übergeben:

namei -l /run/gunicorn.sock
Outputf: /run/gunicorn.sock
drwxr-xr-x root root /
drwxr-xr-x root root run
srw-rw-rw- root root gunicorn.sock

Die Ausgabe zeigt die Berechtigungen der einzelnen Verzeichniskomponenten an. Anhand der Berechtigungen (erste Spalte), des Eigentümers (zweite Spalte) und des Gruppeneigentümers (dritte Spalte) können wir herausfinden, welche Art von Zugriff auf die Socket-Datei zulässig ist.

Im obigen Beispiel verfügen die Socket-Datei und jedes der Verzeichnisse, die zur Socket-Datei führen, über Lese- und Ausführungsberechtigungen für die ganze Welt (die Berechtigungsspalte für die Verzeichnisse endet mit "+ r-x " anstelle von " --- +"). . Der Nginx-Prozess sollte erfolgreich auf den Socket zugreifen können.

Wenn eines der Verzeichnisse, die zum Socket führen, nicht über die Berechtigung zum Lesen und Ausführen auf der ganzen Welt verfügt, kann Nginx nicht auf den Socket zugreifen, ohne die Berechtigungen zum Lesen und Ausführen auf der ganzen Welt zuzulassen oder sicherzustellen, dass einer Gruppe, zu der Nginx gehört, der Besitz einer Gruppe übertragen wird von.

Django zeigt an: "Verbindung zum Server konnte nicht hergestellt werden: Verbindung abgelehnt"

Eine Meldung, die Sie möglicherweise von Django erhalten, wenn Sie versuchen, auf Teile der Anwendung im Webbrowser zuzugreifen, lautet:

OperationalError at /admin/login/
could not connect to server: Connection refused
   Is the server running on host "localhost" (127.0.0.1) and accepting
   TCP/IP connections on port 5432?

Dies zeigt an, dass Django keine Verbindung zur Postgres-Datenbank herstellen kann. Stellen Sie sicher, dass die Postgres-Instanz ausgeführt wird, indem Sie Folgendes eingeben:

sudo systemctl status postgresql

Wenn dies nicht der Fall ist, können Sie es starten und beim Booten automatisch starten (sofern es nicht bereits dafür konfiguriert ist), indem Sie Folgendes eingeben:

sudo systemctl start postgresql
sudo systemctl enable postgresql

Wenn Sie weiterhin Probleme haben, vergewissern Sie sich, dass die in der Datei + ~ / myprojectdir / myproject / settings.py + definierten Datenbankeinstellungen korrekt sind.

Weitere Fehlerbehebung

Zur weiteren Fehlerbehebung können die Protokolle helfen, die Ursachen einzugrenzen. Überprüfen Sie sie nacheinander und suchen Sie nach Meldungen, die auf Problembereiche hinweisen.

Die folgenden Protokolle können hilfreich sein:

  • Überprüfen Sie die Nginx-Prozessprotokolle, indem Sie Folgendes eingeben: + sudo journalctl -u nginx +

  • Überprüfen Sie die Nginx-Zugriffsprotokolle, indem Sie Folgendes eingeben: + sudo less / var / log / nginx / access.log +

  • Überprüfen Sie die Nginx-Fehlerprotokolle, indem Sie Folgendes eingeben: + sudo less / var / log / nginx / error.log +

  • Überprüfen Sie die Gunicorn-Anwendungsprotokolle, indem Sie Folgendes eingeben: + sudo journalctl -u gunicorn +

  • Überprüfen Sie die Gunicorn-Socket-Protokolle, indem Sie Folgendes eingeben: + sudo journalctl -u gunicorn.socket +

Während Sie Ihre Konfiguration oder Anwendung aktualisieren, müssen Sie wahrscheinlich die Prozesse neu starten, um sich an Ihre Änderungen anzupassen.

Wenn Sie Ihre Django-Anwendung aktualisieren, können Sie den Gunicorn-Prozess neu starten, um die Änderungen zu übernehmen, indem Sie Folgendes eingeben:

sudo systemctl restart gunicorn

Wenn Sie den Gunicorn-Socket oder die Servicedateien ändern, laden Sie den Daemon neu und starten Sie den Prozess neu, indem Sie Folgendes eingeben:

sudo systemctl daemon-reload
sudo systemctl restart gunicorn.socket gunicorn.service

Wenn Sie die Nginx-Serverblockkonfiguration ändern, testen Sie die Konfiguration und dann Nginx, indem Sie Folgendes eingeben:

sudo nginx -t && sudo systemctl restart nginx

Diese Befehle sind hilfreich, um Änderungen beim Anpassen Ihrer Konfiguration zu übernehmen.

Fazit

In diesem Handbuch haben wir ein Django-Projekt in einer eigenen virtuellen Umgebung eingerichtet. Wir haben Gunicorn so konfiguriert, dass Kundenanforderungen übersetzt werden, damit Django sie verarbeiten kann. Anschließend haben wir Nginx so eingerichtet, dass es als Reverse-Proxy für die Verarbeitung von Clientverbindungen fungiert und je nach Clientanforderung das richtige Projekt bereitstellt.

Django vereinfacht das Erstellen von Projekten und Anwendungen, indem es viele der gemeinsamen Elemente bereitstellt, sodass Sie sich auf die einzigartigen Elemente konzentrieren können. 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.