Dealing with static files in Django can be confusing on the first project. What does it even mean to serve static files with django? Who hasn’t reached to StackOverflow when setting
debug=False and no images are showing up in the site? The thing is, django only serves static files as an amenity when developing. Once we get to the production stage, it needs to be handled by something else. But first, what are static files?
What are statistic files?
Static files are files that are not generated by the server. Think of the css files, the favicon or images uploaded by your users. They are good candidates for caching and smart delivery since they do not depend on the logic that is present in your django application to be created.
On the other hand, an example of a non-static file is the HTML templates that are shown to the visitor. To be created, they depend on the information stored in the database, or if the user is logged in,for example, so they cannot be decoupled from django.
So, today we will be talking how to fullfil the specific needs of serving static files in django.
I will present three different options, ranging from super simple to enterprisey.
Three options to serve static files with django
Serving static files with a simple django extension
Whitenoise is a Django extension that enables Django to serve static files. To get started just use a simple pip install and off you go. However, you still need to be running django in a uwsgi server, but you’ll be doing that anyway since we are in a production environment, right? This makes whitenoise particularly suitable for running in PaaS offerings like Heroku or digital ocean apps. It is also a no-brainer if your app is not complicated in terms of static files ( composed of just some css and favicons). The cherry on top is that it does some caching and when paired with a CDN like Cloudflare it is a very practical solution without having to worry about configuring services.
The traditional approach: nginx
Pairing a dedicated server with django to serve your static files, and this is most common way to get started. A dedicated server like Nginx enables very fine-tuned control of the settings and enables offloading that workload to a dedicated component while your django app can be focused on processing the payments of your SaaS. The biggest drawback is that it is another thing to maintain and configure – which can be quite startling for the first time.
This ended up being the approach I went for with promozilla. To be honest, I’m very happy with it, after some initial configuration it was fire and forget.
I decided to use nginx to serve the static files. I wrote more in the article I wrote about its architecture. Nginx is a true Swiss army knife since it also does reverse proxy work, load balancer and a lot more.
Lastly, Nginx needs to communicate with django to actually retrieve your sites static files, so not forget to account for that. Using docker-compose this is quite simple using a shared volume.
The big guns: Object Storage Services
This one is the most complex but also most scalable. This is the way to go if you have lots of static files like your app is provided file downloading, video streaming, etc.
It revolves around bringing a third-party service like Amazon S3 or DigitalOcean Spaces to serve your files. Django-storages is an extension that does the heavy lifting for you. This enables a lot of optimization like CDNs so a visitor will fetch the static files from the closest server to him, not just yours, and this reduces loading time. Another good point is this approach provides high reliability (like 11 9’s) and practically infinite scalability – with costs, of course.
One thing to notice is that you will be hosting your data in a third party, with a trade-off of one less thing to worry about and higher costs.
Minio provides object storage with Amazon S3’s interface in a container format if you need to host it locally.
We just discussed what are static files and to deal with them in the context of a django application. We have three solutions, from a simple extension to full-blown object storage services that are suitable to any application. Lastly, although I am using Nginx in promozilla, I would recommend whitenoise for a starting project and if needed move up the complexity.