Serving Media files from nginx


My django app is running on digital ocean and I am using nginx,

I cannot get my media files to my react frontend
I get a 403 Forbidden Error, even after running the chown and chmod command

my nginx/sites-available/ScoringWiz-Backend looks like this
location /media/ {
alias /home/okkertjoubert/pyapps/ScoringWiz-Backend/media/;

location /media/school_logos/ {
    alias /home/okkertjoubert/pyapps/ScoringWiz-Backend/media/school_logos/;

In my I have this
MEDIA_URL = ‘media/’
MEDIA_ROOT = os.path.join(BASE_DIR, ‘media’)


Does the nginx account have access to that directory?

That’s one of the primary reasons why I always suggest that MEDIA_ROOT and STATIC_ROOT get located outside the scope of the project directory, it makes managing permissions easier and safer.

Could you please elaborate on where to store the media files?

When I ran sudo nginx -t all the test were successful. Don’t know if that matters. I have also change ownership and permissions.

The precise answer is that it’s a SysAdmin-type decision, that may depend upon factors outside Django’s control.

For example, for user-uploaded files, you may want that on a volume allocated for that purpose to ensure the total quantity of space used for those files is limited; or is using a file system that may be better suited for the characteristics of the files being uploaded; or is even a file system mounted on a different server.

Or, you may want it to be in a directory that is backed-up by a different process.

Or, you may want this deployed in a Docker environment using a specific data volume for it.

Or, you may be planning to move that directory to something like an AWS S3 bucket, or deploying to a CDN, and you want to ensure that that migration is as painless as possible.

In any event, where you don’t want it, is in your project.

In our case, our common standard is the MEDIA_ROOT is set to /opt/media/<project_name>/.

That’s only verifying that the syntax of the conf files are correct.

What do your nginx logs show for the requests for these files?

So the error logs showed Permission denied,
The journal logs were empty

I ended up running the command chmod -R and the path/to/media as well as chown 644 path/to/media

Rebooted my entire system and restarted Nginx and now it is working

I did try to move the media files to outside of the Django directory and I got the same problem haven’t tried after the reboot.

Yes, you would need to do something like this when media is outside your project directory as well.

The issue is that you’re granting nginx direct access to your project, which creates a security and system-management vulnerability.

As far as the permissions are concerned, our opinion of the best option is that you create your media directory to be owned by the uid of your Django project, with the nginx user (frequently www-data) as the gid for that directory, with the sticky-bit set. You then assign the permissions as 750 for that directory and its contents. (Or 640 for files)

@KenWhitesell can you teach me how serve media files using apache and gunicorn with debug set to false?

If you need assistante for a different topic, open a new question and post what are your configurations.

1 Like