5. Configure static file serving#

The site’s static files need to be handled properly.

The Django runserver provides a lot of convenience. An example is that it will (as long as DEBUG = True) automatically serve static files such as CSS without additional configuration. When you run the site using uWSGI, for example in a cloud deployment, or when DEBUG = False, static files are not automatically served. You can try loading the fonts.css static file in each configuration as a test.

When running with a production server like uWSGI, you need to configure static file serving explicitly. There are multiple ways to do this, but one very good way to do so on the Divio infrastructure is to use the Python library WhiteNoise. WhiteNoise is designed to work behind Content Delivery Networks and integrates well with Django.

Add whitenoise to the requirements.txt:


In settings.py, add it to the list of MIDDLEWARE, after the SecurityMiddleware:


And to have it cache and compress static files, and to tell Django where to put collected static files, at the end of the settings file add:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Rebuild the image to have WhiteNoise installed.

Now, collect the static files to their destination for serving:

docker-compose run web python manage.py collectstatic

You can check that uWSGI and WhiteNoise are serving the static files as expected by:

  • commenting out the command line in docker-compose.yml (to ensure that the runserver isn’t handling them), and

  • setting DEBUG in settings.py to False (to ensure that they aren’t being served by Django’s built-in static file serving).

And now you should be able to load

Revert any temporary changes to docker-compose.yml and settings.py. Then, commit and push your changes (including the new staticfiles directory), deploy the Test environment, and check that static files work as expected there too.

The application can now handle static files, and will do so in an appropriate way for whichever environment the code is running in. The next step is to configure storage and serving of media (i.e. user-uploaded) files.