I attempting to setup a Nginx server up with a Gunicorn WSGI server running Django behind..

The setup all seems to runs except i have a permissions issue. I have setup aliases to /media and a /static directory for serving up static content however a 403 error is generated unless the files are owned by the nginx user.

Files uploaded by the Gunicorn user will obviously be owned by that specific user which will cause a problem. I could add the nginx user to the gunicorn user group however i do not want to give nginx blanket permissions to these files.

What is the suggested method for uploading or generating files via Gunicorn/Wsgi/Django but allow nginx to serve them without adding a security issue.

Thanks in advance,


Blanket permissions to these files are not required. Nginx needs just a read permission. My nginx user account is www-data, gunicorn runs with www_flask privileges. Nginx serves all files uploaded from flask without problems.

File permissions ls -lRr /webroot

total 4
drwxr-xr-x 3 www_flask www_flask 4096 Jul  4 13:20 gunicorn

total 4
drwxr-xr-x 2 www_flask www_flask 4096 Jul  4 14:57 uploads

total 924
-rw-rw-r-- 1 www_flask www_flask 164308 Jul  4 14:55 0001.jpg
-rw-rw-r-- 1 www_flask www_flask  53917 Jul  4 14:56 0004.jpg
-rw-rw-r-- 1 www_flask www_flask 349420 Jul  4 15:07 0005.jpg
-rw-rw-r-- 1 www_flask www_flask 365642 Jul  4 14:56 0006.jpg

nginx config

server {
    server_name localhost;

    location / { 
        try_files $uri @gunicorn_proxy; 

    location /media {
        alias /webroot/gunicorn/uploads/;

    location @gunicorn_proxy {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_redirect off;

Flask upload example from tutorial /home/www_flask/evironments/flask/myapp/myapp.py

import os
from flask import Flask, request, redirect, url_for
from werkzeug import secure_filename

UPLOAD_FOLDER = '/webroot/gunicorn/uploads'

ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])

app = Flask(__name__)

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'],

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return redirect('media/' + filename)
    return '''
    <!doctype html>
    <title>Upload new File</title>
    <h1>Upload new File</h1>
    <form action="" method=post enctype=multipart/form-data>
      <p><input type=file name=file>
         <input type=submit value=Upload>

if __name__ == '__main__':

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.