2012-09-10 44 views
5

我有一個名爲myapp一個Django的管理應用程序,我希望部署在不同物理設備,每個客戶一個多個實例。但是,我希望他們都可以從類似的域名mydomain.com/customer1/myapp訪問。多個Django應用程序和重寫

我撥弄着特定的代理設置,並試圖對SO建議多件事情,但沒有相當適合我的使用情況......因爲我還不是很瞭解兩者nginxdjango我很茫然!

我現在nginx.conf是:

server { 
    listen 80; 
    server_name myserver.com 

    location ^~ /static { 
     alias /path/to/static/files/; 
    } 
# location/{ 
#  proxy_pass http://127.0.0.1:8001; 
# } 
    location ^~ /customer1/myapp/static { 
     alias /path/to/static/files/; 
    } 
    location /customer1/myapp { 
     rewrite ^/customer1/myapp/(/?)(.*) /$2 break; 
     proxy_pass http://127.0.0.1:8001; 
    } 
} 

我可以登錄屏幕通過myserver.com/customer1/myapp/admin預期。但是,當我嘗試登錄時,nginx會將我的網址重寫爲myserver.com/admin,這不是有效的網址。如何讓nginx避免實際重寫url並只更改傳遞給127.0.0.1:8001的url?

FWIW,我使用gunicorn服務與gunicorn -b 127.0.0.1:8001 -n myapp。如果我取消/位置的註釋並刪除最後兩個位置塊,該應用程序效果很好。

我遠非一套這種方法,如果有替代品。目標是避免修改每個部署的django代碼,而只需在nginx.conf中爲新部署添加最少的代碼。

+0

有關部署的問題可能更適合serverfault.com –

+0

我不明白,你只是想讓django url反向生成/ customerX/myapp/admin /而不是/ admin /? – jpic

+0

@jpic不,我想django只能看到根網頁。例如'127.0.0.1:8001/admin'。我假設我可以用nginx做到這一點,但我不知道如何。並指出關於'serverfault.com',我會在那裏發帖,如果我沒有在這裏算出任何東西,謝謝。 – Justin

回答

16

基本上,你指定URL作爲proxy_pass指令的一部分,下面的位置指令應該這樣做:

location ~ ^/customer1/myapp(/?)(.*) { 
    proxy_pass http://127.0.0.1:8001/$2; 
} 

看到http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass爲nginx怎麼通過的URI

+1

謝謝你,我沒有意識到我可以在下面的表達式中使用這些組。然而,這重新寫我的網址在瀏覽器'http://127.0.0.1:8001/$ 2'我寧願它保持原樣。它也不能很好地與django-admin登錄屏幕搭配。 – Justin

+1

這非常適用於大多數應用程序,我接受,但我找到了最好的解決方案是使用子域名'customer.myserver.com',而不是包括在URL中的主要部分客戶。 – Justin

+1

這個答案是一個壞習慣;請參閱http://serverfault.com/a/728792/110020瞭解問題的解釋。 – cnst

3

您應該使用的詳細解釋以下內容:

location /customer1/myapp { 
    return 302 $uri/; 
} 
location /customer1/myapp/ { 
    proxy_pass http://127.0.0.1:8001/ 
} 

注意,這是優於使用內proxy_pass變量,因爲如果你使用變量,那麼proxy_redirect不能再是默認值default,而是off,而內部302重定向到您的應用程序將不會被映射到/customer1/myapp/被nginx提取後,這可能會導致您的麻煩和更多的404s。

而且,是的,使用單獨的域名爲個人客戶是一個好主意,因爲它是更安全(只要cookie處理而言,例如)。