Apprendre à se repérer avec un framework web, par exemple Django, ne suffit pas. Vient un moment où on veut utiliser le site et le déployer. Là, on sort de sa zone de confort de développeur. Typiquement, configurer son serveur pour servir les fichiers statiques peut vite devenir frustrant. C'est un sujet récurrent dans la communauté. S'il vous prend un jour à tâtonner, n'hésitez plus: essayez Whitenoise. Il s'installe en deux lignes et marche pour chaque framework python basé sur wsgi, avec quelques facilités de configuration pour Django.

On a l'embarras du choix pour servir ses fichiers statiques: avec Apache et mod_wsgi, avec ngingx et wsgi ou gunicorn, ou bien avec un CDN, etc. Que ce soit avec Apache ou Nginx, on doit modifier un fichier de conf particulier et il y a plusieurs inconvénients à ceci:

  • c'est "encore un truc à apprendre" et la documentation peut être vieille et absconse. C'est un nouvel obstacle au déploiement pour le nouvel arrivé et une potentielle source de frustration.
  • c'est un fichier externe à notre projet; ou si on l'inclut il faut quand même effectuer une action pour dire au serveur où le trouver (un symlink de sites-enabled par exemple). D'où de nouvelles problématiques si on veut déployer son site comme une boîte prête à l'usage, sans avoir besoin de se connecter au(x) serveur(s) pour écrire des lignes de commandes. Alors on se penche vers Fabric, vers Docker, Guix,…
  • on peut avoir des conflits avec d'autres applications hébergées.

Whitenoise a l'avantage d'être ultra simple et de ne pas avoir besoin de configuration externe au projet.

On l'installe avec pip:

pip install whitenoise

On rajoute 2 lignes à son fichier wsgi.py:

from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise

application = get_wsgi_application()
application = DjangoWhiteNoise(application)

Et voilà.

On peut lancer son serveur, par exemple comme ceci avec gunicorn pour Django:

gunicorn --env DJANGO_SETTINGS_MODULE=myapp.settings myapp.wsgi --bind=<my.server.ip>:8001 --daemon

La doc propose une ligne de conf pour compresser les fichiers ou utiliser un CDN.

On entend souvent que faire servir ses fichiers statiques par Python est une hérésie car c'est beaucoup trop lent. Whitenoise dit:

WhiteNoise est plutôt efficace. Il ne doit servir qu'un ensemble fixe de fichiers donc il peut faire tout le travail de les trouver et de déterminer les headers corrects à l'initialisation. Les requêtes sont alors traitées avec à peine plus de travail qu'un accès dans un dictionnaire. De plus, quand il est utilisé avec gunicorn (ou avec la plupart des serveurs wsgi) l'action même d'envoyer le fichier à l'interface réseau est effectuée par le très efficace appel kernel "sendfile", pas par Python.

Une conversation reddit ne permet pas vraiment de trancher. En tous les cas, vous savez si la performance est un problème pour vous. Pour moi, pas :) Donc je vais développer au lieu de configurer mes serveurs.