I'm using ubuntu 14.04 and running nginx 1.4.6 as reverse proxy server to talk to my django backend which runs on uwsgi. I'm unable to get the internal redirect to work, that is, the request does not reach django at all. Here is my nginx configuration /etc/nginx/site-enabled/default
file. Please let me know what is wrong with my configuration.
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;
}
}
Adding my uwsgi configuration.
[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
Adding my uwsgi startup script
#!/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
/home/northfacing/nfenv is my python environment directory.
If you want django to handle permissions for accessing your media files, first thing to do is to pass all requests into django. I'm assuming that /home/northfacing
is your project root dir (dir where by default manage.py will be placed), your static files are collected into public/static
subdirectory in your project and media files are stored in public/media
.
Basing on that assumptions, here is basic configuration for that behaviour:
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
}
}
Simple explanation: all requests to urls in /media/
are treated as internal, so nginx will serve 404, 401 or 403 error if entered directly. But in that location our proxy server (django in that case) is set as handler, so it will get request and will be able to check if user have access rights.
If there is no access, django can throw it's own error. If acces is granted, django should return an empty response with X-Accel-Redirect
set to file path. Simple view for that can look like this:
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
And in urls.py
:
url(r'^media/', MediaView.as_view(), name="media")