Einrichten von Django mit Postgres, Nginx und Gunicorn unter Ubuntu 16.04

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 wird gezeigt, wie Sie einige Komponenten auf Ubuntu 16.04 installieren und konfigurieren, 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 und Ziele

Um dieses Handbuch zu vervollständigen, sollten Sie eine neue Ubuntu 16.04-Serverinstanz mit einem Nicht-Root-Benutzer mit konfiguriertensudo-Berechtigungen haben. Sie können lernen, wie Sie dies einrichten, indem Sie unsereinitial server setup guide durchlaufen.

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 in HTTP in Python-Aufrufe, die unsere Anwendung verarbeiten kann. 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.

Installieren Sie die Pakete aus den Ubuntu-Repositories

Zu Beginn des Vorgangs laden wir alle benötigten Elemente aus den Ubuntu-Repositorys herunter und installieren sie. Wir werden den Python-Paketmanagerpip verwenden, um zusätzliche Komponenten etwas später zu installieren.

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

Wenn SiePython 2 verwenden, geben Sie Folgendes ein:

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

Wenn Sie Django mitPython 3 verwenden, geben Sie Folgendes ein:

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

Dadurch werdenpip, die Python-Entwicklungsdateien, die zum späteren Erstellen von Gunicorn benötigt werden, das Postgres-Datenbanksystem und die für die Interaktion erforderlichen Bibliotheken sowie der Nginx-Webserver installiert.

Erstellen Sie die PostgreSQL-Datenbank und den Benutzer

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 Namenpostgres erstellt, der dem PostgreSQL-Verwaltungsbenutzerpostgres 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 myproject;

Note

[.note] # Jede Postgres-Anweisung muss mit einem Semikolon enden. Stellen Sie daher sicher, dass Ihr Befehl mit einem endet, wenn Probleme auftreten.
#

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

CREATE USER myprojectuser WITH PASSWORD '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 unsere Django-ProjekteUTC. Dies sind alles Empfehlungen vonthe Django project itself:

ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE myprojectuser 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 myproject TO myprojectuser;

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

\q

Erstellen Sie eine virtuelle 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 Zugriff auf den Befehlvirtualenv. Wir können dies mitpip installieren.

Wenn SiePython 2 verwenden, aktualisieren Siepip und installieren Sie das Paket, indem Sie Folgendes eingeben:

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

Wenn SiePython 3 verwenden, aktualisieren Siepip und installieren Sie das Paket, indem Sie Folgendes eingeben:

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

Wennvirtualenv installiert ist, können wir mit der Erstellung unseres Projekts beginnen. Erstellen Sie ein Verzeichnis und verschieben Sie es in ein Verzeichnis, in dem wir unsere Projektdateien aufbewahren können:

mkdir ~/myproject
cd ~/myproject

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

virtualenv myprojectenv

Dadurch wird ein Verzeichnis mit dem Namenmyprojectenv in Ihrem Verzeichnismyprojecterstellt. Im Inneren wird eine lokale Version von Python und eine lokale Version vonpip 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 myprojectenv/bin/activate

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

Installieren Sie bei aktivierter virtueller Umgebung Django, Gunicorn und den PostgreSQL-Adapterpsycopg2 mit der lokalen Instanzpip:

Note

[.note] # Unabhängig davon, welche Python-Version Sie verwenden, sollten Sie bei Aktivierung der virtuellen Umgebung den Befehlpip verwenden (nichtpip3).
#

pip install django gunicorn psycopg2

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

Erstelle und konfiguriere ein neues Django-Projekt

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

Erstellen Sie das Django-Projekt

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 myproject ~/myproject

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

  • ~/myproject/manage.py: Ein Django-Projektverwaltungsskript.

  • ~/myproject/myproject/: Das Django-Projektpaket. Dies sollte die Dateien__init__.py,settings.py,urls.py undwsgi.py enthalten.

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

Passen Sie die Projekteinstellungen an

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

nano ~/myproject/myproject/settings.py

Suchen Sie zunächst die DirektiveALLOWED_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 einemHost-Header, die nicht in dieser Liste enthalten sind, 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:

~/myproject/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 = ['your_server_domain_or_IP', 'second_domain_or_IP', . . .]

Suchen Sie als Nächstes den Abschnitt, der den Datenbankzugriff konfiguriert. Es beginnt mitDATABASES. 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 mitpip installiertenpsycopg2-Adapter zu verwenden. 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 EinstellungPORTals leere Zeichenfolge belassen:

~/myproject/myproject/settings.py

. . .

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'myproject',
        'USER': 'myprojectuser',
        'PASSWORD': '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 namensstatic im Basisprojektverzeichnis abzulegen:

~/myproject/myproject/settings.py

. . .

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

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

Schließen Sie die anfängliche Projekteinrichtung ab

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

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

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

~/myproject/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:

~/myproject/manage.py collectstatic

Sie müssen den Vorgang bestätigen. Die statischen Dateien werden dann in einem Verzeichnis namensstatic 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:

~/myproject/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://server_domain_or_IP:8000

Sie sollten die Standard-Django-Indexseite sehen:

Django index page

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 Befehlcreatesuperuser erstellt haben:

Django admin login

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

Django admin interface

Wenn Sie mit dem Erkunden fertig sind, drücken Sie im TerminalfensterCTRL-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 undgunicorn verwenden, um das WSGI-Modul des Projekts zu laden:

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

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

[.note] #Note: Auf die Administrationsoberfläche wird kein Styling angewendet, da Gunicorn nicht über den statischen CSS-Inhalt informiert ist, der dafür verantwortlich ist.
#

Wir haben Gunicorn ein Modul übergeben, indem wir den relativen Verzeichnispfad zu Djangoswsgi.py-Datei angegeben haben, die der Einstiegspunkt für unsere Anwendung ist, und dabei die Modulsyntax von Python verwendet haben. In dieser Datei ist eine Funktion namensapplication definiert, mit der mit der Anwendung kommuniziert wird. Um mehr über die WSGI-Spezifikation zu erfahren, klicken Sie aufhere.

Wenn Sie mit dem Testen fertig sind, drücken SieCTRL-C im Terminalfenster, 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.

Erstellen Sie eine Gunicorn System- und Servicedatei

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 eine systemd-Servicedatei.

Erstellen und öffnen Sie eine systemd-Servicedatei für Gunicorn mit den Berechtigungensudoin Ihrem Texteditor:

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:

/etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
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 derwww-data-Gruppe Gruppenbesitz, 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 es an einen Unix-Socket im Projektverzeichnis, da Nginx auf demselben Computer installiert ist. Dies ist sicherer und schneller als die Verwendung eines Netzwerkports. 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
After=network.target

[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/sammy/myproject/myproject.sock myproject.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
After=network.target

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

[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 gunicorn
sudo systemctl enable gunicorn

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

Suchen Sie nach der Gunicorn-Socket-Datei

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

sudo systemctl status gunicorn

Überprüfen Sie als Nächstes, ob die Dateimyproject.sockin Ihrem Projektverzeichnis vorhanden ist:

ls /home/sammy/myproject
Outputmanage.py  myproject  myprojectenv  myproject.sock  static

Wenn der Befehlsystemctl status anzeigt, dass ein Fehler aufgetreten ist, oder wenn Sie die Dateimyproject.sock nicht im Verzeichnis finden, ist dies ein Hinweis darauf, dass Gunicorn nicht richtig starten konnte. Überprüfen Sie die Gunicorn-Prozessprotokolle, indem Sie Folgendes eingeben:

sudo journalctl -u gunicorn

Schauen Sie sich die Meldungen in den Protokollen an, um herauszufinden, wo Gunicorn auf Probleme gestoßen ist. Es gibt viele Gründe, auf die Sie möglicherweise gestoßen sind. Wenn Gunicorn die Socket-Datei jedoch nicht erstellen konnte, kann dies einen der folgenden Gründe haben:

  • Die Projektdateien gehören dem Benutzerrootanstelle des Benutzerssudo

  • Der Pfad vonWorkingDirectoryin der Datei/etc/systemd/system/gunicorn.serviceverweist nicht auf das Projektverzeichnis

  • Die Konfigurationsoptionen für den Prozessgunicorn in der DirektiveExecStart sind nicht korrekt. Überprüfen Sie die folgenden Punkte:

    • Der Pfad zur Binärdateigunicornzeigt auf den tatsächlichen Speicherort der Binärdatei in der virtuellen Umgebung

    • Die Direktive--binddefiniert eine Datei, die in einem Verzeichnis erstellt werden soll, auf das Gunicorn zugreifen kann

    • myproject.wsgi:application ist ein genauer Pfad zum aufrufbaren WSGI. Dies bedeutet, dass Sie inWorkingDirectory in der Lage sein sollten, den aufrufbaren Namenapplication zu erreichen, indem Sie im Modulmyproject.wsgi nachsehen (das in eine Datei mit dem Namen./myproject/wsgi.pyübersetzt wird. s)

Wenn Sie Änderungen an der Datei/etc/systemd/system/gunicorn.servicevornehmen, laden Sie den Dämon neu, um die Dienstdefinition erneut zu lesen, und starten Sie den Gunicorn-Prozess neu, indem Sie Folgendes eingeben:

sudo systemctl daemon-reload
sudo systemctl restart gunicorn

Stellen Sie sicher, dass Sie eines der oben genannten Probleme beheben, bevor Sie fortfahren.

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 imsites-available-Verzeichnis von Nginx:

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

Ö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 server_domain_or_IP;
}

Als Nächstes werden wir Nginx anweisen, Probleme beim Auffinden eines Favicons zu ignorieren. Wir werden auch mitteilen, wo sich die statischen Assets befinden, die wir in unserem Verzeichnis~/myproject/staticgesammelt 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 server_domain_or_IP;

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

Schließlich erstellen wir einenlocation / {}-Block, der allen anderen Anforderungen entspricht. Innerhalb dieses Speicherorts fügen wir die Standarddateiproxy_paramsein, die in der Nginx-Installation enthalten ist, und leiten den Datenverkehr an den Socket weiter, den unser Gunicorn-Prozess erstellt hat:

/etc/nginx/sites-available/myproject

server {
    listen 80;
    server_name server_domain_or_IP;

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

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
    }
}

Speichern und schließen Sie die Datei, wenn Sie fertig sind. Jetzt können wir die Datei aktivieren, indem wir sie mit dem Verzeichnissites-enabledverknüpfen:

sudo ln -s /etc/nginx/sites-available/myproject /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 auch zum Öffnen von Port 8000 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.

Note

[.Hinweis]##

Nach der Konfiguration von Nginx sollte der nächste Schritt die Sicherung des Datenverkehrs zum Server mithilfe von SSL / TLS sein. Dies ist wichtig, da alle Informationen, einschließlich der Passwörter, ohne diese Informationen im Klartext über das Netzwerk gesendet werden.

Wenn Sie einen Domain-Namen haben, können Sie ein SSL-Zertifikat zum Schutz Ihres Datenverkehrs am einfachsten mit Let’s Encrypt erhalten. Folgen Siethis guide, um Let's Encrypt mit Nginx unter Ubuntu 16.04 einzurichten.

Wenn Sie keinen Domainnamen haben, können Sie Ihre Site dennoch mitself-signed SSL certificate.
zum Testen und Lernen sichern

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 einen Proxy für Ihre Anwendung zu erstellen, bedeutet dies normalerweise, dass Sie dieserver_name in der/etc/nginx/sites-available/myproject-Datei anpassen müssen, um auf die IP-Adresse oder den Domänennamen Ihres Servers zu verweisen.

Nginx verwendetserver_name, um zu bestimmen, welcher Serverblock zum Beantworten von Anforderungen verwendet werden soll. Wenn Sie die Standard-Nginx-Seite sehen, ist dies ein Zeichen dafür, dass Nginx die Anforderung nicht explizit einem Serverblock zuordnen konnte, sodass auf den in/etc/nginx/sites-available/default definierten Standardblock zurückgegriffen wird.

Dieserver_name im Serverblock Ihres Projekts müssen spezifischer sein als die 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: /home/sammy/myproject/myproject.sock fehlgeschlagen (2: Keine solche Datei oder kein solches Verzeichnis)

Dies zeigt an, dass Nginx diemyproject.sock-Datei am angegebenen Speicherort nicht finden konnte. Sie sollten den in/etc/nginx/sites-available/myproject definierten Speicherort vonproxy_passmit dem tatsächlichen Speicherort der in Ihrem Projektverzeichnis generiertenmyproject.sock-Datei vergleichen.

Wenn Sie einemyproject.sock-Datei in Ihrem Projektverzeichnis nicht finden können, bedeutet dies im Allgemeinen, dass dergunicorn-Prozess sie nicht erstellen konnte. Gehen Sie zurück zusection on checking for the Gunicorn socket file, um die Schritte zur Fehlerbehebung für Gunicorn durchzuführen.

connect () to unix: /home/sammy/myproject/myproject.sock fehlgeschlagen (13: Berechtigung verweigert)

Dies weist darauf hin, dass Nginx aufgrund von Berechtigungsproblemen keine Verbindung zum Gunicorn-Socket herstellen konnte. Normalerweise geschieht dies, wenn die Prozedur mit dem Root-Benutzer anstelle einessudo-Benutzers ausgeführt wird. Während der Gunicorn-Prozess die Socket-Datei erstellen kann, kann Nginx nicht darauf zugreifen.

Dies kann passieren, wenn zwischen dem Stammverzeichnis (/) und der Dateimyproject.sockan einem beliebigen Punkt eingeschränkte Berechtigungen bestehen. Wir können die Berechtigungen und Besitzwerte der Socket-Datei und jedes ihrer übergeordneten Verzeichnisse anzeigen, indem wir den absoluten Pfad zu unserer Socket-Datei an den Befehlnamei übergeben:

namei -nom /home/sammy/myproject/myproject.sock
Outputf: /home/sammy/myproject/myproject.sock
 drwxr-xr-x root  root     /
 drwxr-xr-x root  root     home
 drwxr-xr-x sammy sammy    sammy
 drwxrwxr-x sammy sammy    myproject
 srwxrwxrwx sammy www-data myproject.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 weltweite Lese- und Ausführungsberechtigungen (die Berechtigungsspalte für die Verzeichnisse endet mitr-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. Für sensible Speicherorte wie das Verzeichnis/rootind beide oben genannten Optionen gefährlich. Es ist besser, die Projektdateien außerhalb des Verzeichnisses zu verschieben, wo Sie den Zugriff sicher steuern können, ohne die Sicherheit zu gefährden.

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

Eine Meldung, die Sie möglicherweise von Django erhalten, wenn Sie versuchen, im Webbrowser auf Teile der Anwendung 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

Ist dies nicht der Fall, 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, stellen Sie sicher, dass die in der Datei~/myproject/myproject/settings.pydefinierten 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

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 die systemd-Dienstdatei vongunicornändern, laden Sie den Dämon neu und starten Sie den Prozess neu, indem Sie Folgendes eingeben:

sudo systemctl daemon-reload
sudo systemctl restart gunicorn

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.