2015-11-20 18 views
2

我正在使用ubuntu 14.04並運行nginx 1.4.6作爲反向代理服務器來與我在uwsgi上運行的django後端進行通信。我無法讓內部重定向工作,也就是說,請求根本沒有達到django。這裏是我的nginx配置/etc/nginx/site-enabled/default文件。請讓我知道我的配置有什麼問題。無法讓nginx內部重定向工作

server { 
     listen 8080; 
     listen 8443 default_server ssl; 
     server_name localhost; 
     client_max_body_size 50M; 
     access_log  /var/log/nginx/nf.access.log; 
     error_log  /var/log/nginx/nf.error_log debug; 
     ssl_certificate  /etc/ssl/nf/nf.crt; 
     ssl_certificate_key /etc/ssl/nf/nf.key; 
     location/{ 
       proxy_pass http://localhost:8000; 
     } 
     location /static/ { 
       root /home/northfacing; 
     } 
     location /media/ { 
       internal; 
       root /home/northfacing; 
     } 
} 

添加我的uwsgi配置。

[uwsgi] 
chdir=/home/northfacing/reia 
module=reia.wsgi:application 
master=True 
pidfile=/home/northfacing/reia/reia-uwsgi.pid 
vacuum=True 
max-requests=5000 
daemonize=/home/northfacing/reia/log/reia-uwsgi.log 
http = 127.0.0.1:8000 

添加我的uwsgi啓動腳本

#!/bin/bash 
USER="northfacing" 
PIDFILE="/home/northfacing/reia/reia-uwsgi.pid" 

function start(){ 
    su - ${USER} /bin/sh -c "source /home/northfacing/nfenv/bin/activate && exec uwsgi --pidfile=${PIDFILE} --master --ini /etc/init.d/reia-uwsgi.ini" 
} 

function stop(){ 
    kill -9 `cat ${PIDFILE}` 
} 

$1 

/家庭/ northfacing/nfenv是我的Python環境目錄。

+0

從什麼URL到你想要重定向的URL? – GwynBleidD

+0

另外,如果您使用uWSGI,請考慮使用本機uwsgi協議('uwsgi_pass')而不是'proxy_pass'。 – GwynBleidD

+0

你做什麼,什麼不工作? –

回答

3

如果您希望django處理訪問媒體文件的權限,首先要做的就是將所有請求傳遞給django。我假設/home/northfacing是您的項目根目錄(dir默認情況下將放置manage.py),您的靜態文件將收集到項目的public/static子目錄中,並且媒體文件將存儲在public/media中。

此基礎上的假設,這裏是該行爲的基本配置:

server { 

    listen 8080; 
    server_name localhost; 

    client_max_body_size 50M; 

    access_log  /var/log/nginx/nf.access.log; 
    error_log  /var/log/nginx/nf.error_log debug; 
    ssl_certificate  /etc/ssl/nf/nf.crt; 
    ssl_certificate_key /etc/ssl/nf/nf.key; 

    root /home/northfacing/public/; 

    location @default { 
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
     proxy_set_header Host $http_host; 
     proxy_redirect off; 
     include /etc/nginx/proxy_params; 

     proxy_pass softwaremind_server; 
     break; 
    } 

    location /static/ { 
     try_files $uri @default; # just some simple default action, so you can show django's 404 page instead of nginx default 
    } 

    location /media/ { 
     internal; 
     error_page 401 403 404 = @default; 
    } 

    location/{ 
     try_files /maintenance.html @default; # you can disable whole page with simple message simply by creating maintenance.html with that message 
    } 
} 

簡單的解釋:/media/到URL的所有請求都被視爲內部,所以nginx的將成爲404,401或403錯誤,如果進入直。但在那個位置,我們的代理服務器(在這種情況下是django)被設置爲處理程序,所以它會得到請求並且能夠檢查用戶是否具有訪問權限。

如果沒有訪問,django可以拋出它自己的錯誤。如果acces被授予,django應該返回一個空的響應,設置爲文件路徑X-Accel-Redirect。對於簡單的視圖可以是這樣的:

class MediaView(View): 

    def get(self, request): 

     if not request.user.is_authenticated(): 
      raise Http404 

     response = HttpResponse() 
     response.status_code = 200 
     response['X-Accel-Redirect'] = request.path 

     # all this headers are cleared-out, so nginx can serve it's own, based on served file 
     del response['Content-Type'] 
     del response['Content-Disposition'] 
     del response['Accept-Ranges'] 
     del response['Set-Cookie'] 
     del response['Cache-Control'] 
     del response['Expires'] 
     return response 

而且在urls.py

url(r'^media/', MediaView.as_view(), name="media") 
+0

感謝您的詳細配置。我仍然面臨的一個問題是,任何以/ media /開頭的uri都不會被轉發到上游。只有在/ nginx配置中有/ media/*時纔會這樣。但是,這會產生一組內部重定向循環,並最終導致nginx拋出500錯誤。仍然在這方面掙扎。 –

+0

檢查我的確切配置,它對我來說很像nginx 1.9.3的魅力。您也可以將'proxy_pass'更改爲'uwsgi_pass'並重新配置您的uWSGI以使用uwsgi協議。檢查uWSGI和django日誌(如果有的話),也許這500錯誤來自他們,而不是從nginx。 – GwynBleidD

+0

希望我能給1個以上upvote。經過幾個小時的試圖找出這個答案,這個答案幫助了我,並且是幾個其他選項,IMO的最佳配置。謝謝! –

0

那是重定向如何工作的內部錯誤我認識。根據以下文檔 http://nginx.org/en/docs/http/ngx_http_core_module.html#internal nginx配置中的內部設置意味着任何具有該外部源的uri的請求將與404一起提供。它必須僅來自內部。在我的情況下,客戶端也使用/ media。所以,這被nginx忽略了。以下配置工作。

在nginx中,我有以下配置。請注意/媒體被刪除。

location /protected/ { 
    internal; 
    alias /home/northfacing/media/; 
} 

location/{ 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header Host $http_host; 
    proxy_redirect off; 
    proxy_pass http://127.0.0.1:8000; 
} 

和蟒蛇的看法,

def protect_uploads(request): 
    if settings.DEBUG == False: 
     response = HttpResponse() 
     response.status_code = 200 
     protected_uri = request.path_info.replace("/media", "/protected") 
     response['X-Accel-Redirect'] = protected_uri 
     del response['Content-Type'] 
     del response['Content-Disposition'] 
     del response['Accept-Ranges'] 
     del response['Set-Cookie'] 
     del response['Cache-Control'] 
     del response['Expires'] 
     logger.debug("protected uri served " + protected_uri) 
     return response 

感謝您的建議。這導致不同的實驗並最終得到修復。