Durch die Entwicklung ihrer Webapplikation in ihrer lokalen Umgebung kommt es häufig zu Problemen beim Deployment auf dem WSGI-fähigen Webserver. Hauptursache sind fehlende oder fehlerhaft gesetzte Datei- und Ordnerberechtigungen. Dieser Post beschäftigt sich mit der notwendigen Konfiguration und enthält Implementierungshinweise für den reibungslosen Betrieb einer WSGI-Applikation auf dem Apache Webserver.

Berechtigungen

Damit der Webserver Ihre WSGI-Applikation korrekt ausführen kann benötigt er Lesezugriff auf alle Dateien und Ordner die dur Applikation gehören.

Der Webserver bezeichnet dabei die Applikation Apache Httpd auf dem Host www (Das www in www.mi.hs-rm.de). Die Applikation wird unter einem eigenen Unix-Benutzer ausgeführt und hat deshalb zunächst keinen Zugriff auf die Dateien in den public_html-Ordnern der einzelnen Nutzer. Die Rechte müssen zunächst gewährt werden.

Für WSGI-Applikationen müssen alle Verzeichnisse und Dateien auf dem Weg zum Applikations-Verzeichnis mindestens lesbar sein (chmod o+r).

Aufbau von URIs/URLs

Relevante Disskusionen um URI, URL, URN auf Stackoverflow:

Mit den wichtigen Antworten:

Eine URI ist wie folgt aufgebaut:

scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]
  • Scheme: http, https, ftp
  • Host z.B.: www.mi.hs-rm.de
  • Port z.B.: 80
  • Path z.B.: ~/username/WSGI/app.wsgi/kunden
  • Query z.B.: ?page=1&orderby=name
  • Fragment: wird vom User-Agent clientseitig ausgewertet, HTML: Anchor auf Seite

Relative Pfade

Pfadanfang Bedeutung
/ Relativ von Wurzel ausgehend
./ Relativ zu aktuellem Verzeichnis
../ Relativ zu übergeordnetem Verzeichnis

Beispiele

URL href Ziel
http://www.mi.hs-rm.de/~user/WSGI/app.wsgi/ /kunde http://www.mi.hs-rm.de/kunde
http://www.mi.hs-rm.de/~user/WSGI/app.wsgi/ ./kunde http://www.mi.hs-rm.de/~user/WSGI/app.wsgi/kunde
http://www.mi.hs-rm.de/~user/WSGI/app.wsgi/ ../kunde http://www.mi.hs-rm.de/~user/WSGI/kunde
http://localhost:8080/ /kunde http://localhost:8080/kunde
http://localhost:8080/ ./kunde http://localhost:8080/kunde
http://localhost:8080/ ../kunde http://localhost:8080/kunde

URLs und Dateipfade im Backend

Häufig werden Module und Dateien nicht gefunden, weil der Webserver die Applikation nicht in ihrem jeweiligen Verzeichnis, sondern in seinem Home- Verzeichnis startet. Ihre Applikation wird allerdings in der Regel relative Pfade, ausgehend vom eigenen Wurzelverzeichnis verwenden.

Damit die relativen Pfade weiterverwendet werden können, muss zunächst beim Start der WSGI-Applikation dafür gesorgt werden, dass das Wurzelverzeichnis im System-Pfad zu finden ist und auch als aktuelles Arbeitsverzeichnis genutzt wird. Die Änderung des Systempfads sorgt dafür, dass der Python-Interpreter des Webservers ihre Module finden kann. Die Änderung des aktuellen Arbeits- verzeichnisses sorgt dafür, dass Sie selbst innerhalb Ihrer Module mit relativen Pfadangaben auf Datein verweisen können (zum Beispiel './Templates/').

Im Folgenden sind zwei Dateien gezeigt, über die Ihre Applikation gestartet werden kann. Die Datei app.wsgi ist dabei lediglich als Einstiegspunkt für den Webserver vorgesehen. Hier wird keinerlei weitere Applikationslogik auf- gerufen oder implementiert.

Die Datei app.py enthält den eigentlichen Einstiegspunkt in Ihre Applikation (die Implementierung der application-Funktion) sowie einen Block zum starten eines lokalen Webservers für die Entwicklung.

app.wsgi

#/usr/bin/env python
#-*- coding:utf-8 -*-
import os
import sys

root_directory = os.path.dirname(__file__)
# Interpreter des Webservers muss Module finden können
sys.path.append(root_directory)
# Eigene Module sollen relative Pfade verwenden können
# z.B.: file('./templates/base.html').read()
os.chdir(root_directory)

from app import application

In der app.wsgi sollte kein Code stehen, der nicht für die Initialisierung der Applikation im WSGI-Kontext des Webservers notwendig ist. Das gezeigte Beispiel initialisiert lediglich die notwendingen Pfade und importiert danach die Funktion application aus dem Modul app.

app.py

#/usr/bin/env python
#-*- coding:utf-8 -*-
import ...
# ...
@Request.application
def application(request):
''' Einstiegspunkt in eigentliche Applikation'''
    return Response("Hello World")
#...
if __name__ == '__main__':
''' startet app mit lokalem Webserver zur Entwicklung '''
   from werkzeug.serving import run_simple
   run_simple('localhost', 4000, application, use_reloader=True)

Das app-Modul implementiert den Einstieg in die eigentliche Applikationslogik. Zustäzlich ist ein Main-Block vorgesehen, um die Applikation lokal mit einem eigenen Webserver auszuführen.

URLs im Frontend

Wenn Sie ihre Software lokal testen, werden Sie in der Regel Pfade verwenden, die folgendem Muster ähneln:

  • http://localhost:8080/<route>

Hier können sie scheinbar problemlos mit Pfaden, relativ zur Wurzel in Ihren Anchor-Tags hantieren (z.B. <a href="/kunden" > ...). Lassen Sie sich davon bitte nicht täuschen. Das führt auf dem Webserver direkt zu folgendem Problem:

Die Basis-URL ihrer Applikation auf dem Webserver lautet http://www.mi.hs-rm.de/~username/WSGI/app.wsgi. Der relative Link zu /kunden unterhalb der Wurzel wird im Browser dann auf folgende URL verweisen: http://www.mi.hs-rm.de/kunden

Diese URL ist NICHT mehr Teil ihrer Applikation.

Um ihre Applikation korrekt verwenden zu können sollten Sie URLs relativ zur Wurzel vermeiden. Bei Einsatz von relativen URLs sollten diese immer relativ zum aktuellen Verzeichnis sein.

Falls das weiterhin problematisch ist, sollten Sie in Betracht ziehen, aussschließlich absolute URLs zu erzeugen. Dazu können Sie das Property url_rootauf Werkzeugs Request-Objekt verwenden.

def render(request):
    ''' generiert eine neue seite für den request '''
    template = file('./templates/navigation.html').read()
    customer_link = request.url_root + 'kunden'
    return template % customer_link

tl;dr

  • Sorgen Sie mit chmod o+r dafür, dass Dateien für den Webserver lesbar sind.
  • Nutzen Sie die .wsgi-Datei dazu, den Webserver seine Arbeit im richtigen Verzeichnis verrichten zu lassen (os.chhdir) und ihre Module auffindbar zu machen (sys.path.append)
  • generieren Sie absolute URLs im Frontend, wenn Sie zu viele Probleme mit relativen URLs haben.

Siehe auch


Sollten Sie Fehler finden, senden Sie mir bitte eine E-Mail.