2015-11-20 9 views
2

Я использую ubuntu 14.04 и запускаю nginx 1.4.6 в качестве обратного прокси-сервера, чтобы поговорить с моим бэкэндом django, который работает на uwsgi. Я не могу заставить внутреннюю переадресацию работать, т. Е. Запрос не достигает джанго вообще. Вот моя конфигурация 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 мой каталог питон среды.

+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/ рассматриваются как внутренние, так 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

Спасибо за подробную конфигурацию. Одной из проблем, с которой я все еще сталкиваюсь, является то, что любой uri начинается с/media/не передается в исходное положение. Это происходит только тогда, когда у меня есть/media/* в конфигурации nginx. Но это делает набор внутренних циклов перенаправления и в конечном итоге 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 у меня есть следующая конфигурация. Обратите внимание, что/media удален.

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 

Спасибо за все ваши предложения. Это приводит к разным экспериментам и, в конечном итоге, к исправлению.