2012-07-02 12 views
14

Voglio eseguire un semplice progetto di test in un alias di sottodirectory sul nostro server di sviluppo. L'impostazione di base è un nginx con una posizione che passa tutto in una sottodirectory all'applicazione wsgi.Esegui l'applicazione django via nginx + uwsgi in un sottotracciato

Django ovviamente non capisce che viene eseguito in un alias di sottodirectory, che distrugge completamente la generazione e l'analisi degli URL.
Non sono riuscito a trovare alcuna impostazione di prefisso nei documenti e anche il mio google fu non mi è servito molto ... quindi mi sto chiedendo qui.

L'unica cosa che ho trovato era l'impostazione FORCE_SCRIPT_NAME che almeno corregge la generazione di URL. (vedi: http://docs.webfaction.com/software/django/config.html#mounting-a-django-application-on-a-subpath)
Purtroppo questo non risolve l'analisi urlconf, anche se il sito menzionato lo suggerisce.

È possibile eseguire un'applicazione django in un alias di sottodirectory e, in caso affermativo, come?

nginx config:

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

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

Modifica

Così, impostando "uwsgi_param SCRIPT_NAME/fancyprojectname;" nella posizione di nginx non è necessario FORCE_SCRIPT_NAME, purtroppo la corrispondenza dell'URL non funziona ancora.

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)), 
) 

Quello che penso quello che sta succedendo: Come l'espressione regolare amministratore inizia con "^ admin" e l'URL reale è "fancyprojectname/admin /", Django può non corrisponde correttamente gli URL, anche se lo SCRIPT_NAME è impostato.

La soluzione

Così, è stato davvero un problema con SCRIPT_NAME.

Il WSGI specification dice il seguente:

SCRIPT_NAME La parte iniziale di "percorso" del URL di richiesta che corrisponde all'oggetto applicazione, in modo che l'applicazione conosce la sua virtuale "location". Questa potrebbe essere una stringa vuota, se l'applicazione corrisponde alla "radice" del server.

PATH_INFO Il resto del "percorso" dell'URL della richiesta, che designa la "posizione" virtuale della destinazione della richiesta all'interno dell'applicazione. Questo può essere una stringa vuota, se l'URL della richiesta è rivolto alla root dell'applicazione e non ha una barra finale.

Nginx non imposta SCRIPT_NAME automaticamente, quindi è necessario impostarlo in ogni caso. In seguito PATH_INFO è sbagliato, perché nella configurazione predefinita Nginx lo imposta su $ document_uri, che sarebbe l'URL completo.

"uwsgi_modifier1 30;" dice a Nginx di impostare UWSGI_MODIFIER_MANAGE_PATH_INFO, che a sua volta dice a UWSGI di rimuovere lo SCRIPT_NAME del PATH_INFO.

La combinazione di queste impostazioni sembra funzionare, poichè Django ora può generare AND abbinare correttamente gli URL.

+0

prega di dare un'occhiata al https://stackoverflow.com/a/40496307/1588163 Vi si possono trovare il modo aggiornato per raggiungere questo obiettivo – clapas

+0

[Vedi anche : Come montare l'App Django con uwsgi] (https://stackoverflow.com/questions/19475651/how-to-mount-django-app-with-uwsgi) –

risposta

7

Questo è falso:

Django, ovviamente, non capisce che venga eseguito in un alias sottodirectory, che distrugge completamente la generazione di URL e di analisi.

Django non capire che, e si occupa di esso in modo trasparente. Il server dovrebbe impostare SCRIPT_NAME stesso: il fatto che tu ti stia utilizzando FORCE_SCRIPT_NAME dimostra che il problema si trova nella configurazione Nginx, piuttosto che in Django.

Ho il sospetto che il problema sia l'uso di location, piuttosto che una direttiva più adatta. Purtroppo non sono esperto di Nginx/uwsgi. In Apache/mod_wsgi, si dovrebbe fare questo:

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

per dire mod_wsgi quel sito inizia alle mysite, piuttosto che la radice. C'è quasi certamente un comando simile con nginx/uwsgi.

+3

Ok, l'ho provato con "uwsgi_param SCRIPT_NAME/fancyprojectname;" in nginx e questo sembra "funzionare", dal momento che ora posso commentare FORCE_SCRIPT_NAME nelle impostazioni e gli URL sono generati correttamente - questo comunque non aggiusta la corrispondenza degli URL. Aggiungerò l'attuale configurazione dell'URL nella domanda. – Strayer

+5

Sembra che stia funzionando ora: SCRIPT_NAME non lo era, impostando "uwsgi_modifier1 30;" lo fa comunque. Non ho idea di cosa sia questa impostazione, ma quando lo scoprirò aggiornerò di nuovo la domanda e la accetterò come risposta valida. Grazie per il puntatore! – Strayer

+0

Grazie @Strayer. Ha funzionato per me :) –

5

Se questo blocco posizione Nginx funziona quando ospita il sito Django a http://www.example.com/ (il dominio di base):

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

allora questo lavoro a http://www.example.com/subpath/ (un sottotracciato sul tuo dominio di base):

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

... e non è necessario impostare FORCE_SCRIPT_NAME nelle impostazioni di Django.

Riferimenti:

+0

Grazie, ora ho [Hatta wiki] (http://hatta-wiki.org/) in esecuzione in un sottotracciato sotto nginx. –

+0

Non dimenticare di aggiungere "env = DJANGO_SETTINGS_MODULE = your_app.settings" al tuo file uwsgi.ini. –

Problemi correlati