DEV Community

Cover image for The Right Way to serve static files when using Django with Gunicorn
Prahlad Yeri
Prahlad Yeri

Posted on • Originally published at prahladyeri.com

The Right Way to serve static files when using Django with Gunicorn

Yesterday, I learned during deployment that your Django app when used in combination with gunicorn will refuse to serve static files, do whatever you may. I looked up almost every Stack Overflow answer post on this topic including this, this and this.

I meddled with almost every hopeful setting including STATICFILES_DIRS[], STATIC_ROOT and STATIC_URL but to no avail. Its as if Django is designed to refuse serving of static files when using gunicorn and that's what I started to suspect after everything failed.

And my suspicion was almost confirmed by this post which says that:

Gunicorn will only serve the dynamic content, i.e. the Django files

But I know that's not strictly true because I've used Gunicorn with Flask in the past and it serves static files of your Flask app without any issues at all!

But then I thought that its better to handle static files using nginx anyway and since I was already using nginx as the front proxy on my server anyway, I thought of trying that post's suggestion. As mentioned, I added a new location section to my nginx configuration file as follows:

location /static {
        autoindex on;
        alias /path/to/staticfiles;
    }
Enter fullscreen mode Exit fullscreen mode

And that's exactly what worked! I bypassed gunicorn entirely and static files are now being served directly by the front server and I think this is a more efficient setup than having gunicorn serve the static files.

But why gunicorn/django refuse to serve static files directly still remain a mystery. I think the problem lies somewhere in Django and not gunicorn because as I said, I've seen gunicorn serve Flask static files before.

Discussion (3)

Collapse
prahladyeri profile image
Prahlad Yeri Author • Edited on

Yep, I've read that django docs page and feel that it shows a needlessly confusing and lengthy process. For example, it really makes no sense to have an additional collectstatic process just to copy static files from one folder to other!

$ python manage.py collectstatic
Enter fullscreen mode Exit fullscreen mode

All this does is copy your files from one static folder in your project directory (say "/static/") to another (say "/staticfiles/"). But doing none of that will actually make django serve those static files on production -especially when there is an additional layer like gunicorn. The StackOverflow is filled with these issues. I think django should outright refuse to serve static on production instead of covertly/silently failing in this manner!