KrISS feed 8.7 - A simple and smart (or stupid) feed reader. By Tontof
  • Tuesday 21 July 2015 - 19:20

    Je vois souvent passer des questions sur le forums ou autres fils de discussion concernant la mise en production d'un projet Django.
    Ici je vais présenter une façon de faire, utilisant Nginx Gunicorn et Supervisord .

    Prérequis

    Sur une Débian toute fraiche,

    Nginx

    sudo apt-get install nginx
    

    Virtualenv

    Car nous travaillons toujours avec un environnement virtuel, dans lequel nous allons y installer les dépendances de notre projet.
    Ce qui permet de ne pas avoir de conflit de version avec d'autres éventuels projets déjà en prod.

    pip install virtualenv virtualenvwrapper
    

    Note : Si vous n'avez pas l'outil pip de disponible, installez-le comme ceci

    sudo apt-get install python-setuptools
    sudo easy_install pip
    

    Puis dans votre fichier ~/.bashrc , ajoutez les lignes suivantes, pour l'autocompletion

    export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-package'
    export WORKON_HOME=$HOME/.virtualenvs
    source /usr/local/bin/virtualenvwrapper.sh
    

    Gunicorn

    Pourquoi pas utiliser uWSGI ? humm ... car je préfère Gunicorn qui me donne toute satisfaction sur mes projets en prod. donc ... pourquoi pas !

    sudo apt-get install libevent-dev
    pip install gunicorn
    

    Supervisor

    Installation simple :

    sudo pip install supervisor
    

    Récupération du fichier de conf par défaut

    echo_supervisord_conf > /etc/supervisord.conf
    

    Dans le fichier de conf, afin de pouvoir manager votre projet via l'interface web, il faut dé-commenter et paramétrer les lignes suivantes

    [inet_http_server]         ; inet (TCP) server disabled by default
    port=*:9001        ; (ip_address:port specifier, *:port for all iface)
    username=user              ; (default is no username (open server))
    password=123               ; (default is no password (open server))
    

    Note: Changer le username et password évidemment

    L'interface web sera disponible à l'adresse : http://ipduserveur:9001

    Pour le lancement automatique au démarrage du système, vous pouvez utiliser ces scripts d'init:

    1. debian init supervisor
    2. debian init supervisor

    Installer votre projet

    Notre environnement est prêt, nous allons commencer par installer le projet Django dans l’environnement virtuel.

    Création du virtualenv

    mkvirtualenv monprojet
    

    Si vous utilisez git, cloner votre projet, sinon, copier le à l'endroit que vous souhaitez, ( pour l'exemple ce sera /var/www/monprojet )

    Installation des dépendances du projet

    si vous utilisez également les environnements virtuels pour développer ( ce que je conseille ) vous pouvez alors enregistrer la liste des libs python installées dans cette environnement, afin de pouvoir également les installer ( avec la même version ) sur un autre serveur.

    Pour avoir la liste des libs :

    pip freeze > requirements.txt
    

    puis sur votre serveur, pour installer les libs depuis un export freeze :

    pip install -r requirements.txt
    

    Configuration de Django

    Il vous faudra peut-être toucher un peu à votre fichier settings.py pour le passer du mode debug au mode production.
    Personnellement j'utilise une autre subtilité qui me permet de ne pas avoir à toucher au fichier settings.py ( j'expliquerai celà dans un autre billet ) .

    N'oubliez pas de vérifier le paramètre STATIC_ROOT

    STATIC_ROOT = '/var/www/static_monprojet/'
    

    C'est le répertoire ou seront copiés les fichiers statiques du projet, pour ensuite être servis par Nginx

    Ce répertoire DOIT EXISTER

    Une fois le répertoire créé, nous allons y "placer/lier" les fichiers statiques du projet

    python manage.py collectstatic --link
    

    Perso je préfère y mettre des liens symboliques .. ( les gouts et les couleurs ... )

    Liaison du projet avec Gunicorn

    Nous allons créer un fichier dans notre projet qui sera utilisé pour le lancement du/des process Gunicorn ( vous devrez adapter les valeurs dans ce script )

    vim /var/www/monprojet/monprojet/gunicorn.sh
    

    Et voici le contenu

    #!/bin/bash
      set -e
      NUM_WORKERS=2
      USER=www-data
      GROUP=www-data
      ADDRESS=127.0.0.1:5002
      cd /var/www/monprojet
      source /home/monuser/.virtualenvs/monprojet/bin/activate
      exec gunicorn monprojet.wsgi:application -w $NUM_WORKERS --bind=$ADDRESS \
        --user=$USER --group=$GROUP --log-level=debug
    

    Puis on le rend exécutable

    chmod 777 /var/www/monprojet/monprojet/gunicorn.sh
    

    Configuration Supervisord

    Notre projet est prêt, afin de lancer Gunicorn automatiquement, nous allons utiliser supervisord, qui en plus de s'occuper de démarrer le projet automatiquement au démarrage du système, va aussi le relancer en cas de crash, gérer les logs et vous donner la main pour arrêter ré-demarrer les process, via l'interface web ou en mode console.

    supervisord.png

    Ajoutez à la fin du fichier de configuration /etc/supervisord.conf les lignes suivantes ( paramètres à adapter selon votre cas )

    [program:guni_monprojet]
    directory=/var/www/monprojet/monprojet
    user = www-data
    autostart=true
    autorestart=true
    stdout_logfile=/var/log/monprojet.log
    redirect_stderr=true
    stopsignal=QUIT
    command = /var/www/monprojet/monprojet/monprojet.sh
    

    Ne reste plus qu'à redémarrer supervisor pour prendre en compte la nouvelle config.

    Pour le lancer manuellement

    sudo supervisord -c /etc/supervisord.conf
    

    Vhost Nginx

    Dernier point, la création du vhost de Nginx, pour diriger les requêtes vers Gunicorn qui écoute sur le port 5002 ( il est aussi possible d'utiliser un fichier socket à la place )

    vim /etc/nginx/sites-enabled/monprojet
    

    Et voilà le contenu ( fonctionnel, mais vous pouvez l'adapter )

    upstream us_monprojet {
            server 127.0.0.1:5002;
    }
    
    
    server {
            listen 80;
    
            root /var/www/monprojet;
    
            gzip             on;
            gzip_min_length  1000;
            gzip_proxied     expired no-cache no-store private auth;
            gzip_types       text/plain application/xml text/css text/javascript application/x-javascript application/x-shockwave-flash video/x-flv;
            gzip_disable     "MSIE [1-6]\.";
    
    
            server_name monprojet.com;
            charset utf-8;
    
            client_max_body_size 75M;
    
    
            location ~ /\.ht {
                deny  all;
            }
    
            location /favicon.ico {
                    alias /var/www/monprojet/monprojet/static/favicon.ico;
    
                    if (-f $request_filename) {
                            access_log off;
                            expires max;
                    }
    
            }
    
    
            location /media {
                    alias /var/www/monprojet/monprojet/media;
    
                    if (-f $request_filename) {
                            access_log off;
                            expires max;
                    }
    
            }
    
            location /static {
                    alias /var/www/static_monprojet/;
    
                    if (-f $request_filename) {
                            access_log off;
                            expires max;
                    }
    
            }
    location / {
    
                    if (-f $request_filename) {
                            access_log off;
                            expires max;
                    }       
    
                    #gunicornParams
                    if (!-f $request_filename) {
                            proxy_pass         http://us_monprojet;
                            break;
                    }       
                    proxy_redirect     off;
                    proxy_set_header   Host             $host;
                    proxy_set_header   X-Real-IP        $remote_addr;
                    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    
            }       
    }       
    
    

    Ne reste plus qu'à activer le vhost, et relancer nginx

    ln -s /etc/nginx/sites-available/monprojet /etc/nginx/sites-enabled/
    service nginx reload