NGINX Unit mit Python / Django

Mittlerweile gibt es eine Vielzahl von Möglichkeiten eine Webanwendung zu entwickeln und sie dem Anwender zur Verfügung zu stellen. Eine einfache und schnelle Variante, das zu erreichen, ist mit Hilfe von NGINX Unit.

In diesem Beitrag werden die wichtigsten Komponenten und Schritte erläutert, um erfolgreich eine kleine Anwendung zu erstellen. 

NGINX Unit

NGINX Unit ist ein Applikations-Server, der es uns erlaubt Webapplikationen aus verschiedenen Programmiersprachen und Frameworks zu deployen, zu hosten und zu konfigurieren. Wir haben damit die Möglichkeit auf sehr unterschiedliche Weise Probleme zu lösen und den Vorteil, dass das Know-How über den Applikations-Server nicht verloren geht, wenn wir unsere gewünschte Sprache ändern. Die Verwendung von NGINX Unit bietet zudem den Vorteil, Applikationen ohne Downtime zu konfigurieren. Dies erfolgt zur Laufzeit per REST-Schnittstelle des NGINX Unit.

Container

In welcher Umgebung die Anwendung später laufen soll, muss vor Beginn der Entwicklung geklärt werden. Das Django Projekt wird in unserem Bespiel in einem Docker-Container verwirklicht. Es wäre aber auch möglich NGINX Unit direkt auf dem Host zu installieren.

Der Vorteil der Docker-Variante ist, dass wir unsere Anwendung deployen können, ohne uns groß um die darunterliegende Umgebung kümmern zu müssen. Für NGINX Unit steht von NGINX ein base-image zur Verfügung, auf dem wir im Folgenden aufbauen.

Die Anwendung

Zu Beginn erzeugen wir eine lauffähige Django Applikation, indem wir mit Hilfe des „django-admin“ tools die Grundstruktur des Projektes erzeugen. Auf der Django Homepage sind Tutorials und Dokumentation, um sich mit dem Framework vertraut zu machen. Folgendes diente zur Orientierung: https://docs.djangoproject.com/en/3.1/.

Im Laufe der Entwicklung ist es notwendig, sich alle anfallenden Abhängigkeiten zu notieren. Wir machen das in einem Textdokument namens „requirements.txt“. In unserem Fall gehört hier also mindestens Django hinein. Diese Abhängigkeiten müssen später auch in unserem Docker Container installiert werden.

NINGX Konfiguration

Nachdem wir unsere Anwendung generiert haben, müssen wir eine Konfiguration für unseren NGINX Unit Serverprozess erstellen.

Die wichtigsten Dinge die diese Konfiguration klären muss, sind:

  • Wo im Container/Host befindet sich unser Projekt?
  • Auf welchem Port soll die Applikation horchen?
  • In welcher Sprache wurde unsere Applikation geschrieben?

In unserem Fall sieht die Applikationskonfiguration für NGINX Unit wie folgt aus: 

In diesem Fall horcht die Applikation auf port 8080. Es handelt sich um eine Python Anwendung und im Docker Container ist das Django Projekt unter /www/nginx zu finden.

Wichtig ist hier auch das Feld “module”. Hier wird eingetragen, wo sich unsere wsgi.py befindet. „nginx.wsgi“ bedeutet, innerhalb unseres Django Projekts existiert eine Datei wsgi.py im Ordner nginx, als Einstiegspunkt in die Applikationslogik.

Der absolute Pfad unserer Datei ergibt sich somit als „/www/nginx/nginx/wsgi.py“

Mehr zu den Möglichkeiten, die mit der NGINX Unit Konfiguration zur Verfügung stehen, findet ihr unter: https://unit.nginx.org/configuration/

Docker Image

Unsere letzte Komponente ist das Docker-Image, aus diesem Docker-File:

Wie oben erwähnt stellt uns NGINX ein base image für NGINX Unit, für unterschiedliche Programmiersprachen und in unterschiedlichen Ausführungen, zur Verfügung. Wir haben in unserem Beispiel ein Image gewählt, das mehrere Programmiersprachen unterstützt. Für den produktiven Einsatz kann es sinnvoller sein auf spezialisierte Images zu setzen.

Folgender Link listet eine Übersicht über die verfügbaren Images auf: https://hub.docker.com/r/ngix/unit

Der erste Schritt den unser Docker Image ausführt, ist das Kopieren unseres NGINX Unit config files nach /docker-entrypoint.d/config.json. Dadurch erreichen wir, dass unsere Konfiguration als Startkonfiguration des NGINX Units verwendet wird.

Als nächstes fügen wir die o.g. Liste von Abhängigkeiten in unser Image ein. Auf diese Weise sind wir in der Lage über unser „package management tool“ alle benötigten Abhängigkeiten nachladen zu lassen.

Dann wird unser Django Projekt an die richtige Position in unserem Image gebracht. Hier ist es wichtig, dass dieser Pfad mit dem Pfad aus der NGINX Konfiguration übereinstimmt.

Zuletzt installieren wir alle nötigen Abhängigkeiten und geben den Port frei, den wir auch in der NGINX Unit Konfiguration angegeben haben.

Das Docker Image kann nun gebaut und der Container gestartet werden. Beim Start muss darauf geachtet werden, dass das Mapping des NGINX Unit Ports nach außen erfolgt. Die Anwendung kann nun über den Docker Host aufgerufen werden.