Django svn et mod_wsgi, attention au piège!
Scénario
Notre cher utilisateur biboul se décide à installer la version de développement de django, que nous appellerons django-trunk, comme indiqué sur la page How To Install Django.
Il lance donc les commandes suivantes:
biboul@laptop:~$ svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk biboul@laptop:~$ ln -s `pwd`/django-trunk/django /usr/lib/python2.5/site-packages/django biboul@laptop:~$ ln -s `pwd`/django-trunk/django/bin/django-admin.py /usr/local/bin
Il a bien entendu
- configuré son serveur apache pour utiliser le module WSGI
- testé avec le script wsgi « hello world » que la configuration était bonne
- modifié le script wsgi de manière à utiliser son application django mysite
Le problème
Lors de la première requête à son application mysite, une belle « 500 Internal Server Error » s’affiche, avec les messages d’erreurs suivants dans le fichier /var/log/apache2/error_log:
... mod_wsgi (pid=5803): Target WSGI script '/opt/tcs/tcs.wsgi' cannot be loaded as Python module. ... mod_wsgi (pid=5803): Exception occurred processing WSGI script '/opt/tcs/tcs.wsgi'. ... Traceback (most recent call last): ... File "/opt/tcs/tcs.wsgi", line 6, in <module> ... import django.core.handlers.wsgi ... ImportError: No module named django.core.handlers.wsgi
Mais pourquoi donc, alors qu’un import django.core.handlers.wsgi fonctionne correctement, que ce soit dans l’interpréteur ou dans le shell django?
La réponse
Tout simplement parce que le répertoire django-trunk (dont notre cher utilisateur biboul a fait un lien symbolique dans le répertoire site-packages) n’est pas accessible à un utilisateur différent, si il n’est pas dans le même group.
Or, par défaut et sur la plupart des distributions Linux, les processus apache sont lancé avec un utilisateur limité (www-data, www ou encore apache).
La solution
Un simple chmod 755 des répertoires parents au répertoire django-trunk est suffisant pour régler ce problème.
Une autre solution, plus propre et sécurisée, serait de placer le répertoire django-trunk dans le répertoire /opt, et de modifier les liens symboliques pour utiliser ce nouvel emplacement.
Ce billet peut être utile, mais il est mal nommé. Il n’y a ici rien de spécifique à Django, ni à mod_wsgi.
Personnellement, même sur ma machine personnelle de développement et test, j’évite de dire à mon serveur de lire des fichiers d’un autre utilisateur.
Cordialement, Merwok
Merci pour ce retour!
Effectivement, ce n’est pas un problème spécifique à django, ni à mod_wsgi. Néanmoins, vu que je l’ai rencontré d’une manière tout à fait « naturelle » (en suivant la méthode indiquée sur la doc de django), je me suis dit que ça servirait à d’autres
Je suis d’accord avec toi, la solution proposée (le chmod) est un « dirty hack », et absolument pas à utiliser dans un environnement de production.
L’idéal serait bien entendu de soit utiliser la version stable de django (et donc de la faire installer par un egg sur le serveur par exemple), soit si on est un peu aventureux (et qu’on est assez vigilant pour mettre en production une version de dev de django, et la suivre au quotidien), faire en sorte que ce soit l’utilisateur utilisé par le serveur web qui détiennent les fichiers.
Un chown serait donc une meilleure solution, voire tout simplement l’installation du repository svn directement dans un répertoire accessible par l’utilisateur www-data par exemple pour apache, comme indiqué en « seconde solution ».