2012-07-02 10 views
14

Ich möchte ein einfaches Testprojekt in einem Unterverzeichnis Alias ​​auf unserem Entwicklungsserver ausführen. Das grundlegende Setup ist ein Nginx mit einem Speicherort, der alles in einem Unterverzeichnis an die wsgi-Anwendung übergibt.Ausführen von Django-App über Nginx + uwsgi in einem Unterpfad

Django offensichtlich nicht verstehen, dass es in einem Unterverzeichnis Alias ​​ausgeführt wird, die vollständig URL-Generierung und Parsing zerstört.
Ich konnte keine Präfix-ähnliche Einstellung in den Dokumenten finden und mein Google Fu half auch nicht so viel ... also frage ich stattdessen hier.

Das einzige, was ich gefunden habe, war die Einstellung FORCE_SCRIPT_NAME, die zumindest die URL-Generierung behebt. (siehe: http://docs.webfaction.com/software/django/config.html#mounting-a-django-application-on-a-subpath)
Traurig dies repariert nicht die URLconf-Analyse, obwohl die erwähnte Website das vorschlägt.

Ist es möglich, eine Django-Anwendung in einem Unterverzeichnis-Alias ​​auszuführen, und wenn ja, wie?

nginx config:

server { 
     location /fancyprojectname/static { 
       alias /srv/fancyprojectname/static; 
     } 

     location /fancyprojectname/ { 
       uwsgi_pass unix://var/run/uwsgi/app/fancyprojectname/socket; 
       include uwsgi_params; 
     } 
} 

bearbeiten

So "uwsgi_param SCRIPT_NAME/fancyprojectname;" -Einstellung in der Nginx-Position macht FORCE_SCRIPT_NAME unnötig - leider funktioniert die URL-Übereinstimmung immer noch nicht.

from django.conf.urls import patterns, include, url 

# Uncomment the next two lines to enable the admin: 
from django.contrib import admin 
admin.autodiscover() 

urlpatterns = patterns('', 
    # Uncomment the admin/doc line below to enable admin documentation: 
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), 

    # Uncomment the next line to enable the admin: 
    url(r'^admin/', include(admin.site.urls)), 
) 

Was ich denke, was passiert ist: Da der Admin-regex mit „^ admin“ beginnt und die tatsächliche URL „fancyprojectname/admin /“ Django können die URLs nicht richtig passen, obwohl die SCRIPT_NAME ist einstellen.

Die Lösung

So war es in der Tat ein Problem mit SCRIPT_NAME.

Die WSGI specification sagt der folgende:

SCRIPT_NAME Der erste Teil der „Weg“ des Anforderungs-URL, die auf das Anwendungsobjekt entspricht, so dass die Anwendung seiner virtuellen „location“ kennt. Dies kann eine leere Zeichenfolge sein, wenn die Anwendung dem "root" des Servers entspricht.

PATH_INFO Der Rest des "Pfads" der Anforderungs-URL, der den virtuellen "Standort" des Ziels der Anforderung in der Anwendung angibt. Dies kann eine leere Zeichenfolge sein, wenn die Anforderungs-URL auf das Anwendungsstammziel ausgerichtet ist und keinen abschließenden Schrägstrich hat.

Nginx legt SCRIPT_NAME nicht automatisch fest, daher muss dies in jedem Fall festgelegt werden. Danach ist PATH_INFO falsch, weil Nginx in der Standard-Konfiguration dies auf $ document_uri setzt, was die vollständige URL wäre.

"uwsgi_modifier1 30;" weist Nginx an, UWSGI_MODIFIER_MANAGE_PATH_INFO zu setzen, was wiederum UWSGI mitteilt, SCRIPT_NAME von PATH_INFO zu entfernen.

Die Kombination dieser Einstellungen scheint zu funktionieren, da Django URLs jetzt UND korrekt erstellen kann.

+0

haben Sie einen Blick auf https://stackoverflow.com/a/40496307/1588163 Dort finden Sie die aktualisierte Weg finden, diese – clapas

+0

[erreichen Siehe auch : Wie mount Django App mit uwsgi] (https://stackoverflow.com/questions/19475651/how-to-mount-django-app-with-uwsgi) –

Antwort

7

Das ist falsch:

Django offensichtlich nicht verstehen, dass es in einem Unterverzeichnis alias läuft, die vollständig URL-Generierung und Analyse zerstört.

Django ist verstehen, dass Qualität, Sicherheit und damit transparent. Der Server sollte SCRIPT_NAME selbst festlegen: Die Tatsache, dass Sie FORCE_SCRIPT_NAME verwenden, zeigt, dass das Problem in Ihrer Nginx-Konfiguration und nicht in Django liegt.

Ich vermute, dass das Problem ist die Verwendung von location, anstatt eine geeignetere Richtlinie. Leider bin ich kein Experte für Nginx/uwsgi. In Apache/mod_wsgi, würden Sie dies tun:

WSGIScriptAlias /mysite /usr/local/django/mysite/apache/django.wsgi 

zu sagen mod_wsgi, dass vor Ort beginnt bei mysite, anstatt die Wurzel. Es ist fast sicher ein ähnliches Kommando mit nginx/uwsgi.

+3

Okay, ich habe das mit "uwsgi_param SCRIPT_NAME/fancyprojectname;" in nginx und das scheint "zu funktionieren", da ich nun FORCE_SCRIPT_NAME in den Einstellungen auskommentieren kann und die URLs korrekt generiert werden - das behebt jedoch immer noch keine URL-Übereinstimmung. Ich füge die aktuelle URL-Konfiguration in die Frage ein. – Strayer

+5

Es sieht so aus, als ob es jetzt funktioniert - SCRIPT_NAME wurde nicht eneugh, Einstellung "uwsgi_modifier1 30;" tut es aber. Ich habe keine Ahnung, was diese Einstellung bewirkt, aber wenn ich es herausfinde, werde ich die Frage erneut aktualisieren und diese als gültige Antwort akzeptieren. Danke für den Zeiger! – Strayer

+0

Danke @Strayer. Es funktionierte für mich :) –

5

Wenn dieser Nginx Standort Block funktioniert, wenn die Django-Site unter http://www.example.com/ (Ihre Basis Domain) Hosting:

location/{ 
    uwsgi_pass unix:/tmp/fancyprojectname.socket; 
    include /etc/nginx/uwsgi_params; 
} 

Dann wird dies bei http://www.example.com/subpath/ arbeiten (eine subpath auf Basis Domain):

location /subpath { 
    uwsgi_pass unix:/tmp/fancyprojectname.socket; 
    uwsgi_param SCRIPT_NAME /subpath; # explicitly set SCRIPT_NAME to match subpath 
    uwsgi_modifier1 30; # strips SCRIPT_NAME from PATH_INFO (the url passed to Django) 
    include /etc/nginx/uwsgi_params; 
} 

... und Sie müssen FORCE_SCRIPT_NAME nicht in Ihren Django-Einstellungen festlegen.

Referenzen:

+0

Danke, jetzt habe ich [Hatta Wiki] (http://hatta-wiki.org/) in einem Unterpfad laufen unter nginx. –

+0

Vergessen Sie nicht, "env = DJANGO_SETTINGS_MODULE = your_app.settings" zu Ihrer uwsgi.ini-Datei hinzuzufügen. –

Verwandte Themen