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"
}