2011-11-15 10 views
18

Ho un'applicazione django in esecuzione su http://localhost:12345. Vorrei che l'utente accedesse tramite l'url http://my.server.com/myapp. Io uso nginx per invertire delega ad esso come il seguente:come distribuire django sotto un suburl dietro nginx

... ... 
server_name my.server.com; 
location /myapp { 
    rewrite /myapp(.*) $1 break;   
    ... ... # proxy param 
    proxy_pass http://localhost:12345; 
} 
... ... 

la domanda è, se configurato come sopra, come fare le URL in mie pagine di risposta di avere un prefisso di "/ myapp" in modo che il nginx può indirizzarli correttamente a myapp. Ad esempio, gli URL di una pagina come "/ foo/far" dovrebbero essere cambiati in "/ myapp/foo/bar" per consentire al proxy nginx su myapp. qual è il giusto nginx configure da usare per raggiungere questo?

Posso usare le variabili di impostazione di django per specificare il prefisso dell'URL di root, ma non è flessibile per la mia mente, poiché la variabile deve essere modificata in base alla configurazione di nginx (diciamo che un giorno nginx può cambiare il suburl da "/ myapp "a"/anotherapp ").

risposta

11

Poiché il prefisso è impostato in Nginx, il server Web che ospita l'app Django non ha modo di conoscere il prefisso URL. Come detto da orzel, se hai usato apache + mod_wsgi anche di nginx + gunicorn/uwsgi (con qualche configurazione aggiuntiva), potresti usare il valore WSGIScriptAlias, che viene automaticamente letto da Django.

Quando ho bisogno di usare un prefisso URL, io in genere metto io stesso nel mio urls.py radice, dove ho una sola linea, preceduto dal prefisso e tra cui un altro urls.py

(r'^/myapp/', include('myapp.urls')), 

Ma immagino che questo abbia lo stesso collo di bottiglia che impostare un prefisso in settings.py, hai una configurazione ridondante in nginx e Django.

È necessario eseguire un'operazione sul server che ospita l'app Django al numero: 12345. Puoi impostare il prefisso lì e passarlo a Django usando WSGIScriptAlias ​​o il suo equivalente all'esterno di mod_wsgi. Non posso dare ulteriori informazioni in quanto non so come viene eseguita la tua applicazione Django. Inoltre, forse dovresti prendere in considerazione l'esecuzione della tua app Django direttamente da Django, usando uWSGI o gunicorn.

per passare il prefisso per Django dal server web, è possibile utilizzare questo:

proxy_set_header SCRIPT_NAME /myapp; 

Maggiori informazioni here

+1

Grazie, Suona come devo andare con il trucco WSGIScriptAlias ​​ –

+2

Grazie al cielo per questo post. Il trucco "proxy_set_header" mi ha salvato da un incubo della ricerca di Google. Avrei dovuto saperlo meglio. Gracias. –

2

Di seguito è parte della mia configurazione per nginx che, in effetti, non imposta FORCE_SCRIPT_NAME, ma, quindi, non sto utilizzando una sottodirectory. Forse sarà utile per impostare le opzioni relative a USE_X_FORWARDED_HOST in nginx piuttosto che in Django.

upstream app_server_djangoapp { 
    server localhost:8001 fail_timeout=0; 
} 

server { 
    listen xxx.xxx.xx.xx:80; 
    server_name mydomain.com www.mydomain.com; 
    if ($host = mydomain.com) { 
     rewrite ^/(.*)$ http://www.mydomain.com/$1 permanent; 
    } 
    ... 
    location/{ 
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
     proxy_set_header Host $http_host; 
     proxy_redirect off; 

     if (!-f $request_filename) { 
      proxy_pass http://app_server_djangoapp; 
      break; 
     } 
    } 
    ... 
}