Maintenant que Nginx est correctement configuré pour servir Redmine, c’est au tour de Django de passer à la casserole (bah ouais, Python ou Ruby, s’pas un troll qui m’affecte des masses :–°)
Comme pour Redmine, Nginx fera office de reverse proxy, mais cette fois ce sera via FastCGI que sera servi le contenu.
Je suppose toujours que vous avez un Nginx opérationnel et Ubuntu 10.4, les manips doivent ici aussi être les mêmes pour tous les dérivés Debian. Mais cette fois j’ajouterai un pré-requis supplémentaire : un projet django fonctionnel (bawé, cay kewl si on veut tester =P)
Installation des .deb
sudo aptitude install python-django python-flup
Et voilà, on a une install’ de Django fonctionnelle, et de quoi faire tourner un serveur FastCGI.
Automatisation du lancement des projets Django
Parce qu’il peut être sympa de pouvoir lancer/stopper/relancer automatiquement tous les projets django que l’on sert, je vous mets à disposition un script à placer dans /etc/init.d/django_fastcgi et à rendre exécutable via le traditionnel :
sudo chmod +x /etc/init.d/django_fastcgi
N.B : prenez bien soin de correctement renseigner la variable DJANGO_SITES. Elle doit contenir les chemins sans le slash final vers les projets, séparés par des espaces. Chaque path présent dans DJANGO_SITES doit permettre d’accéder au fichier manage.py qui correspond au projet, ce fichier permettant dans notre cas de lancer le serveur FastCGI.
#! /bin/sh ### BEGIN INIT INFO # Provides: FastCGI servers for Django # Required-Start: networking # Required-Stop: networking # Default-Start: 2 3 4 5 # Default-Stop: S 0 1 6 # Short-Description: Start FastCGI servers with Django. # Description: Django, in order to operate with FastCGI, must be started # in a very specific way with manage.py. This must be done # for each Django web server that has to run. ### END INIT INFO # # Authors: Guillermo Fernandez Castellanos # <guillermo.fernandez.castellanos AT gmail.com>. # # Kévin Gomez # <geek63 AT gmail.com>. # # Version: @(#)fastcgi 0.1 18-Jul-2010 geek63 AT gmail.com # @(#)fastcgi 0.1 11-Jan-2007 guillermo.fernandez.castellanos AT gmail.com # #### SERVER SPECIFIC CONFIGURATION DJANGO_SITES="/home/kevin/project_foo /home/bar/project_foo" RUNFILES_PATH=/tmp HOST=127.0.0.1 PORT_START=3030 RUN_AS=www-data FCGI_METHOD=prefork #### DO NOT CHANGE ANYTHING AFTER THIS LINE! set -e PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DESC="FastCGI servers" NAME=$0 SCRIPTNAME=/etc/init.d/$NAME # # Function that starts the daemon/service. # d_start() { # Starting all Django FastCGI processes PORT=$PORT_START for SITE in $DJANGO_SITES do PID_FILE=`echo $SITE | sed -e 's#/#_#g'` if [ -f $RUNFILES_PATH/$PID_FILE.pid ]; then echo "$SITE already running" else start-stop-daemon --start --pidfile $RUNFILES_PATH/$PID_FILE.pid \ --startas /usr/bin/python $SITES_PATH/$SITE/manage.py runfcgi \ method=$FCGI_METHOD socket=$RUNFILES_PATH/$PID_FILE.socket \ pidfile=$RUNFILES_PATH/$PID_FILE.pid chmod 400 $RUNFILES_PATH/$PID_FILE.pid chmod 777 $RUNFILES_PATH/$PID_FILE.socket echo "$SITE started" fi PORT=$(($PORT + 1)) done } # # Function that stops the daemon/service. # d_stop() { # Killing all Django FastCGI processes running for SITE in $DJANGO_SITES do PID_FILE=`echo $SITE | sed -e 's#/#_#g'` start-stop-daemon --stop --quiet --pidfile $RUNFILES_PATH/$PID_FILE.pid & echo "$SITE stopped" \ || echo -n "$SITE not running" if [ -f $RUNFILES_PATH/$PID_FILE.pid ]; then rm $RUNFILES_PATH/$PID_FILE.pid fi done } ACTION="$1" case "$ACTION" in start) echo "Starting $DESC:" d_start ;; stop) echo "Stopping $DESC:" d_stop ;; restart|force-reload) echo "Restarting $DESC:" d_stop sleep 1 d_start ;; *) echo "Usage: $NAME {start|stop|restart|force-reload}" >&2 exit 3 ;; esac exit 0
On peut aussi faire en sorte que les projets soient automatiquement lancés dès le boot du serveur via un :
sudo update-rc.d django_fastcgi defaults
Configuration de Nginx
Un exemple de virtualhost vaut mieux qu’un long discours, donc le voici :
server { listen 80; server_name domain.tld; location / { fastcgi_pass unix:/tmp/_home_bar_project_foo.socket; # à vous de voir si vous avez besoin de plus de choses fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param SERVER_NAME $server_name; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; } # on sert directement les fichiers statiques de l'administration location /media { root /usr/lib/python2.5/site-packages/django/contrib/admin/media; } # quelques fichiers statiques liés à l'application (css, images, js) location /static { root /home/bar/project_foo; } }
L’adresse du socket peut est connue via la méthode suivante :
- $RUNFILES_PATH : définie dans /etc/init.d/django_fastcgi
- $PROJECT_PATH : correspond à l’adresse du projet dans laquelle on a remplacé les « / » par des « _ »
- l’adresse du socket est : $RUNFILES_PATH/$PROJECT_PATH.socket
Une fonction très basique en bash permet d’automatiser la douloureuse et complexe conversion de chemin :
# elle prend en paramètre le path à convertir, et si aucun paramètre n'est fourni elle utilise le répertoire courant fastcgi_sockfile() { if [ "$1" = "" ]; then SITE=`pwd` else SITE=$1 fi echo "/tmp/`echo $SITE | sed -e 's#/#_#g'`.sock" }