NGINX Conf 2018: NGINX Unit für Produktionsanwendungen konfigurieren – Bereitstellung eines Django-Projekts

NGINX | 28. November 2018

NGINX Unit ist ein vollständig dynamischer Anwendungsserver, der mehrere Sprachen sowie mehrere Versionen jeder Sprache unterstützen kann. Dynamisch bedeutet hier, dass Sie über die RESTful-JSON-API Änderungen an seiner Konfiguration im Arbeitsspeicher vornehmen können, ohne den Dienst zu unterbrechen oder die Konfiguration neu zu laden.

In meinem Vortrag auf der NGINX Conf 2018 im Oktober zeigte ich, wie sich eine neue Anwendung in einer bestehenden Produktionsumgebung konfigurieren lässt. Konkret stellte ich neben WordPress, das auf PHP lief, eine Python-Anwendung bereit, die das Django-Framework verwendet. Außerdem zeigte ich, wie sich die Konfiguration sowohl aus einer Datei als auch über ein Argument eines API-Aufrufs laden lässt.

Dieser Blogbeitrag enthält alle Befehle und Konfigurationscodes, die ich in der Demo verwendet habe, damit Sie sie leichter an Ihre eigene Bereitstellung anpassen können.

Voraussetzungen

Für die Demo auf der NGINX Conf hatte ich die folgende Software installiert:

  • Ubuntu 16.04
  • NGINX Plus, Sie können jedoch NGINX Open Source verwenden, sofern nicht anders angegeben
  • NGINX Unit mit allen installierten Sprachmodulen
  • Python 3
  • Django (nicht konfiguriert – genau darum geht es in der Demo und in diesem Blog)
  • root-Berechtigungen oder gleichwertiger Zugriff über sudo (das wir bei Bedarf verwenden)

Außerdem waren PHP und WordPress bereits als bestehende Anwendung installiert.

Erstellen des Django-Projekts

  1. Wechsle in das Verzeichnis, in dem wir unser Django-Projekt erstellen:
$ cd /var/www/
  1. Verwenden Sie den Befehl „django-admin startproject“, um das neue Projekt zu initialisieren. Wir nennen es „djapp“.
$ sudo django-admin startproject djapp
  1. Wechseln Sie in das Projektverzeichnis:
$ cd djapp
  1. Verwenden Sie das Skript „manage.py“, um die Datenbank für das Projekt zu migrieren. Dies ist bei einem neu erstellten Projekt erforderlich. Django verwendet standardmäßig SQLite. In der Demo übernehme ich diese Standardeinstellung, Sie können jedoch jede Datenbank verwenden, die den Anforderungen Ihres Projekts entspricht. Das Skript „manage.py“ wird durch den Befehl „django-admin“ installiert, den wir in Schritt 2 ausgeführt haben. Es führt dieselben Befehle aus und akzeptiert dieselben Argumente wie „django-admin“, ermittelt und verwendet jedoch automatisch einige projektspezifische Einstellungen, was sehr hilfreich ist. Weitere Informationen finden Sie in der Django-Dokumentation.
$ sudo python3 manage.py migrate
  1. Obwohl dies für ein Beispielprojekt wie dieses nicht unbedingt erforderlich ist, empfehlen wir Ihnen, eine Django-Superuser-Identität zu erstellen:
$ sudo python3 manage.py createsuperuser
  1. Wechseln Sie in das Unterverzeichnis, das die Datei „settings.py“ enthält. Dieses wurde in Schritt 2 mit dem Befehl django-admin startproject erstellt.
$ cd /var/www/djapp/djapp
  1. Öffnen Sie settings.py mit Ihrem bevorzugten Texteditor. Hier verwenden wir nano:
$ sudo nano settings.py
  1. Suchen Sie die Zeile ALLOWED_HOSTS und fügen Sie den Domänennamen, Hostnamen oder die IP-Adresse der Anwendung hinzu:
ALLOWED_HOSTS = ['domain-name']
  1. Fügen Sie außerdem am Ende der Datei die folgende Zeile hinzu, um das Verzeichnis anzugeben, in dem alle von der Anwendung bereitgestellten statischen Inhalte gespeichert werden (siehe Schritt 9).
STATIC_ROOT = '/var/www/djapp/djapp/static'
  1. Wechseln Sie zurück in das Hauptprojektverzeichnis (in dem sich manage.py befindet).
$ cd ..
  1. Führen Sie den Befehl „manage.py collectstatic“ aus, um alle statischen Dateien im Django-Projekt zu erfassen und am in Schritt 7 definierten Speicherort STATIC_ROOT abzulegen.
$ sudo python3 manage.py collectstatic

NGINX konfigurieren

Standardmäßig stellt Django die statischen Inhalte eines Projekts selbst bereit, doch NGINX Open Source und NGINX Plus bieten eine höhere Leistung. Hier konfigurieren wir NGINX Plus, Sie können jedoch auch NGINX Open Source verwenden – mit Ausnahme einer unten beschriebenen Funktion.

  1. Wechseln Sie in das Verzeichnis /etc/nginx/conf.d, den üblichen Speicherort für funktionsspezifische (oder in unserem Fall anwendungsspezifische) HTTP-Konfigurationsdateien:
$ cd /etc/nginx/conf.d
  1. Erstellen Sie eine Datei namens „django.conf“ (wir verwenden wieder nano):
$ sudo nano django.conf
  1. Fügen Sie die folgende Konfiguration ein, die das Caching aktiviert. Die Konfiguration enthält außerdem zwei Funktionen, die ausschließlich in NGINX Plus verfügbar sind. Entfernen Sie die Kommentarzeichen vor den entsprechenden Direktiven, wenn Sie NGINX Plus verwenden und diese Funktionen nutzen möchten. Beachten Sie, dass ich bei der Demo auf der NGINX Conf die IP-Adresse meines lokalen Rechners als zweites Argument für die Direktive proxy_set_header angegeben habe. In einer Produktionsumgebung ist es sinnvoller, wie unten gezeigt die Variable $host zu verwenden.
# Upstream group for the backend (NGINX Unit running the Python application)
upstream django_unit {
    zone django_unit 64k;
    server 127.0.0.1:8000;
}
 
server {
    listen 8080;
    # Uncomment to collect metrics if using NGINX Plus and the NGINX Plus API
    #status_zone django;
      	
    # enable caching
    proxy_cache django_cache;
    proxy_cache_valid 200 60m;
 
    # root directory for static files
    root /var/www/djapp/djapp;
 
    # proxy to the NGINX Unit backend
    location / {
        proxy_pass http://django_unit;

        # Second argument must match your production hostname and the value of 
        # ALLOWED_HOSTS in settings.py
        proxy_set_header Host $host; 
 
        # Uncomment to enable active health checks if using NGINX Plus
        #health_check;
    }

    # Location for the static files collected from Django and served by 
    # NGINX Plus; can be empty (as here), because it inherits the value of the 
    # 'root' directive from its parent block
    location /static {
    }
}
  1. Überprüfen Sie die Konfiguration auf syntaktische Gültigkeit:
$ sudo nginx –t
  1. Nachdem Sie alle Fehler behoben haben, laden Sie die Konfiguration neu:
$ sudo nginx -s reload

NGINX Unit konfigurieren

Abschließend müssen wir NGINX Unit so konfigurieren, dass Anfragen an die Anwendung weitergeleitet werden.

  1. Führen Sie diesen curl-Befehl aus, um die aktuelle NGINX Unit-Konfiguration anzuzeigen, die für WordPress unter PHP eingerichtet ist. Die Ausgabe wird hier nicht gezeigt, aber die WordPress-Konfiguration ist unten in Schritt 6 zusammen mit der Konfiguration der Python-Anwendung zu sehen, die wir gleich hinzufügen. Beachten Sie, dass ich für den sudo-Befehl curl verwende, was bei den meisten curl-Befehlen möglicherweise nicht erforderlich ist. Hier ist es notwendig, da wir für den Zugriff auf den UNIX-Socket die Lese- und Schreibberechtigung benötigen, die root dafür besitzt.
$ sudo curl --unix-socket /run/control.unit.sock http://localhost/config/
  1. Wechseln Sie in das Verzeichnis für die Konfigurationsdateien von NGINX Unit. Beachten Sie, dass diese Dateien optional sind und lediglich eine bequeme Möglichkeit bieten, Konfigurationssammlungen zu laden, ohne sämtliche Daten als Argument bei einem Aufruf der NGINX Unit API eingeben zu müssen. Da der Inhalt der Dateien über die API hochgeladen wird (wie alle Konfigurationsdaten), kennt NGINX Unit die Speicherorte der Dateien nicht und kann sie beim Start nicht automatisch einlesen (anders als NGINX Open Source und NGINX Plus). Stattdessen speichert NGINX Unit seinen Laufzeitstatus in einem separaten Verzeichnis.
$ cd /etc/unit
  1. Erstellen Sie eine Datei namens „django.config“ (wir verwenden wieder nano):
$ sudo nano django.config
  1. Fügen Sie das folgende JSON hinzu, das unsere Python-Anwendung darstellt.
{
      "type": "python",
      "processes": 5,
      "module": "djapp.wsgi",
      "path": "/var/www/djapp"
}
  1. Führen Sie diesen curl-Befehl aus, um die in django.config enthaltenen JSON-Daten als neues, von NGINX Unit zu verwaltendes Anwendungsobjekt namens djapp zu laden:
$ sudo curl -X PUT --data-binary @/etc/unit/django.config --unix-socket /run/control.unit.sock http://localhost/config/applications/djapp
  1. In diesem Befehl:
    • Die HTTP-PUT-Methode erstellt ein neues NGINX Unit-Konfigurationsobjekt an dem durch das letzte Argument (die URL) angegebenen Speicherort. Siehe den letzten Aufzählungspunkt unten.
    • Das Argument „--data-binary“ weist curl an, den Inhalt von django.config exakt wie angegeben zu laden, wobei Zeilenumbrüche und Wagenrückläufe beibehalten werden und keinerlei Verarbeitung erfolgt.
    • Das Argument „--unix-socket“ gibt an, wo die NGINX Unit-API lauscht. (Wir verwenden den Befehl „sudo“, da wir den standardmäßigen Eigentümer des Sockets verwenden: „root“.)
    • Das letzte Argument gibt den Speicherort und den Namen des neuen Anwendungsobjekts an, das mit den JSON-formatierten Konfigurationsdaten aus django.config befüllt werden soll: config ist das oberste NGINX Unit-Konfigurationsobjekt, applications das übergeordnete Objekt für Anwendungsobjekte und djapp der Name des neuen Anwendungsobjekts.
  2. Definieren Sie das Listener-Objekt für die Anwendung. Anstatt wie in Schritt 4 eine Datei mit Konfigurationsdaten zu laden, geben wir die Daten direkt in der curl-Befehlszeile an und legen fest, dass die Anwendung djapp Port 8000 überwacht.
$ sudo curl -X PUT --data-binary '{"application":"djapp"}' --unix-socket /run/control.unit.sock 'http://localhost/config/listeners/*:8000'
  1. Wiederholen Sie den curl-Befehl aus Schritt 1, um die NGINX Unit-Konfiguration anzuzeigen, die nun auch unsere Python-Anwendung djapp enthält, die orange hervorgehoben ist:
$ sudo curl --unix-socket /run/control.unit.sock http://localhost/config/{
      "listeners": {
            "127.0.0.1:8090": {
                  "application": "script_index_php"
            },
 
            "127.0.0.1:8091": {
                  "application": "direct_php"
            },
 
            "*:8000": { "application": "djapp" }
      },
 
      "applications": {
            "script_index_php": {
                  "type": "php",
                  "processes": {
                        "max": 20,
                        "spare": 5
                   },
 
                  "user": "www-data",
                  "group": "www-data",
                  "root": "/var/www/wordpress",
                  "script": "index.php"
            },
 
            "direct_php": {
                  "type": "php",
                  "processes": {
                        "max": 5,
                        "spare": 0
                  },
 
                  "user": "www-data",
                  "group": "www-data",
                  "root": "/var/www/wordpress",
                  "index": "index.php"
                  },
 
            "djapp": { "type": "python", "processes": 5, "module": "djapp.wsgi", "path": "/var/www/djapp" }
      }
}

Zusammenfassung

In diesem Beitrag sind wir von NGINX Unit ausgegangen, auf dem PHP-Anwendungen für WordPress in einer Produktionsumgebung ausgeführt werden, und haben eine Python-Anwendung hinzugefügt. In der Demo zeige ich anhand des NGINX Plus-Dashboards, dass das Hinzufügen einer neuen Anwendung den Betrieb der vorhandenen Anwendungen nicht beeinträchtigt. Sie können zu diesem Zweck jedoch auch ein beliebiges Systemüberwachungstool verwenden, beispielsweise den Befehl „ps“. Die dynamische Konfiguration von NGINX Unit spart Ressourcen für Ihre laufenden Anwendungen und gewährleistet bei neuen Bereitstellungen einen unterbrechungsfreien Betrieb sowie einen reibungslosen Übergang zwischen Anwendungsversionen.

Weitere Informationen finden Sie unter unit.nginx.org.


Teilen
Schlagwörter: Python, F5 NGINX, Tech

Ähnliche Blogbeiträge

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln
NGINX | 23.08.2022

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln

Beim NGINX Sprint 2022 besinnen wir uns auf unsere Open-Source-Wurzeln. Erfahren Sie mehr über die Initiativen, die wir im kommenden Jahr verfolgen, und teilen Sie uns mit, was Sie sich wünschen.

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen
NGINX | 08.09.2021

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen

Ein Ingress-Controller kann eines der leistungsstärksten Tools in Ihrem Kubernetes-Stack sein. Erfahren Sie, wie Sie Ihre Ingress-Anforderungen ermitteln, um die beste Option auszuwählen.

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet
NGINX | 16.08.2021

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet

Wir haben kürzlich den Lösungsleitfaden zum NGINX Ingress Controller um Empfehlungen zur Dimensionierung für Amazon Elastic Kubernetes Service (EKS) ergänzt. In diesem Blogbeitrag erläutern wir, wie wir diese Empfehlungen erarbeitet haben, und stellen Ihnen alle Informationen zur Verfügung, die Sie benötigen, um selbst ähnliche Tests durchzuführen.

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77
NGINX | 12.12.2018

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77

Bei der Fehlersuche bei Datenverkehrsproblemen zwischen NGINX und Upstream-Servern konnte CDN77 die benötigten Daten nur aus dem Fehlerprotokoll mit aktivierter Debug-Ausgabe beziehen, was die Leistung beeinträchtigt und riesige Dateien erzeugt. Daher entwickelte das Team ein neues benutzerdefiniertes Modul, das ausschließlich die benötigten Daten protokolliert.

Ankündigung von NGINX Plus R16
NGINX | 05.09.2018

Ankündigung von NGINX Plus R16

NGINX Plus R16 ist eine einheitliche, elastische Ingress- und Egress-Schicht für Anwendungen, die die Funktionen eines Load Balancers, API-Gateways und einer WAF vereint und neue Features wie clusterfähige Ratenbegrenzung, Schlüssel-Wert-Speicher, „Random with Two Choices“, verbessertes UDP-Load-Balancing und vieles mehr bietet.

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing
NGINX | 13.10.2016

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing

Entdecken Sie fünf Gründe für den Wechsel zu einem softwarebasierten Load Balancer wie NGINX Plus, darunter Kosteneinsparungen, die Einführung von DevOps und eine einheitliche Lösung für alle Umgebungen.