lindev.fr

Aller au contenu | Aller au menu | Aller à la recherche

28 déc. 2016

HAProxy LetsEncrypt et Varnish en front .. rien que ça

L'objectif final

Avoir l'ensemble de ses sites accessibles en https, avec des certificats letsencrypt ( gratuits et surtout renouvelés automatiquement ) et un serveur de cache ( varnish ) pour augmenter la capacité de charge ( bref optimiser les perfs des sites ) pour enfin passer le relais au backend ( Apache, Nginx .. peu importe ).

network_diagram_user_haproxy_varnish_apache.png

le hic

Il y en a toujours un ... et pas des moindres cette fois, varnish ne gère pas l'https !

La solution - TLS Termination Proxy

L'utilisation d'un proxy ( HAProxy ) pour gérer les transactions Https, puis relayer en clair les requêtes vers varnish qui à son tour si nécessaire va relayer les requêtes au(x) serveur(s) ( Apache/Nginx/... )

Plusieurs avantages à cette solution ( Terminaison SSL ), soulager les serveurs finaux ( Apache/Nginx ... ) de la gestion du SSL et surtout pour nous admins, nous simplifier la tâche pour ce qui est de la gestion des certificats.

Dans ce billet

Dans ce billet, je ne vais parler que de HAProxy et letsencrypt pour commencer, varnish étant un assez gros morceau, il fera l'objet d'un second billet.

Mise en place de la situation

Vous pouvez utiliser un seul et même serveur pour héberger l'ensemble de ces services ... mais franchement ça ne devrait jamais être le cas ! Donc pour ce billet nous allons partir du principe que nous possédons 2 serveurs .

Le premier pour héberger HAProxy et Varnish ( 10.0.0.1 ) et le second pour héberger le serveur HTTP ( 10.0.0.2 )

Les deux serveurs sont sous Debian 8 (Jessie).

Serveur HAProxy

Commençons par Installer HAProxy ( plus quelque trucs utils dans ce "tuto" ) ... qui se fait simplement par

apt install haproxy bc vim 

Commençons par copier le fichier de configuration par defaut

cd /etc/haproxy/
cp haproxy.cfg haproxy.cfg.orig


Maintenant nous pouvons éditer le fichier /etc/haproxy/haproxy.cfg

vim /etc/haproxy/haproxy.cfg

Remplacer tout le contenu par :

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # Default ciphers to use on SSL-enabled listening sockets.
        # For more information, see ciphers(1SSL). This list is from:
        #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
        ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
        ssl-default-bind-options no-sslv3

        maxconn 2048
        tune.ssl.default-dh-param 2048

defaults
        #log    global
        log     /dev/log local0
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

        option forwardfor
        option http-server-close


#################################

frontend www-http
        bind *:80
        mode http

        #option httpclose
        option forwardfor
        option httplog
        option dontlognull

        reqadd X-Forwarded-Proto:\ http
        default_backend www-backend


frontend www-https
        bind *:443 ssl crt /etc/haproxy/certs/
        mode http
        reqadd X-Forwarded-Proto:\ https

        #option httpclose
        option forwardfor
        option httplog
        option dontlognull

        acl letsencrypt-acl path_beg /.well-known/acme-challenge/
        use_backend letsencrypt-backend if letsencrypt-acl

        default_backend www-backend


backend www-backend

        #option httpclose
        option forwardfor

        http-request set-header X-Forwarder-Port %[dst_port]
        redirect scheme https if !{ ssl_fc }
        server www-1 10.0.0.2:80 check

backend letsencrypt-backend
        server letsencrypt 127.0.0.1:54321


listen stats *:1936
        stats enable
        stats uri /
        stats hide-version
        stats auth username:password

Comme vous l'avez certainement remarqué, nous allons chercher les certificats dans le répertoire /etc/haproxy/certs/ qui n'éxiste pas encore.
Créons le

sudo mkdir /etc/haproxy/certs
sudo chmod -R go-rwx /etc/haproxy/certs

Voilà pour HAProxy, nous verrons ensuite dans l'interface de statistics si tout est ok .

Letsencrypt et certbot

Pour la génération des certificats, nous allons utiliser l'outil certbot .
Pour l'installer nous allons devoir activer ( si ce n'est déjà fait ) le dépôt BlackPorts de Debian

sudo echo 'deb http://ftp.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/blackports.list
apt update

On install certbot depuis ce dépôt

apt-get install certbot -t jessie-backports

Afin d'initialiser letsencrypt, nous allons le lancer une première fois

certbot certonly

Celà ne va pas aboutir, c'est normal, c'est juste pour qu'il crée les répertoires de base.

Celà ne vous a pas échappé, le port 80 est déjà utilisé par HAProxy, et ne peu donc être utilisé par Letsencrypt pour générer ou renouveler un certificat.
L'idée de couper HAProxy le temps de cette action est inconcevable, nous allons simplement utiliser un autre port. ( ici : 54321 )

Pour ne pas avoir à le spécifier à chaque commande, nous allons mettre en place un petit fichier de configuration pour définir quelques paramètres qui ne changent pas . ( ce qui va nous permettre de raccourcir nos lignes de commandes plus tard ).

sudo cd /etc/letsencrypt/ && vim cli.ini

Voici le contenu

# This is an example of the kind of things you can do in a configuration file.
# All flags used by the client can be configured here. Run Certbot with
# "--help" to learn more about the available options.

# Use a 4096 bit RSA key instead of 2048
rsa-key-size = 4096

# Uncomment and update to register with the specified e-mail address
email = admin@your.net

# Uncomment to use a text interface instead of ncurses
text = True

standalone-supported-challenges = http-01

Afin de tester l'ensemble de notre configuration, nous allons générer notre premier certificat ( manuellement ) .
Imaginons que le domaine soit "lindev.fr" :

sudo certbot certonly --standalone --http-01-port 54321 -d lindev.fr -d www.lindev.fr
sudo cat /etc/letsencrypt/live/lindev.fr/fullchain.pem /etc/letsencrypt/live/lindev.fr/privkey.pem > /etc/haproxy/certs/lindev.fr.pem
sudo service haproxy restart

Bien entendu, il faut que le nom de domaine "lindev.fr" et "www.lindev.fr" pointent sur l'ip de mon serveur ( HAProxy ).

HAProxy est maintenant prêt . Je suppose que le backend ( Nginx ou Apache ) est déjà configuré avec un vhost écoutant sur le port 80 pour le domaine "lindev.fr et www.lindev.fr".

Et voilà le résultat. Capture_d_e_cran_2017-01-03_a__21.15.37.png

Renouvellement automatique

Nous allons maintenant faire en sorte que les certificats LetsEncrypt se régénèrent automatiquement avant expiration et ce tant qu'à faire sans intervention nécessaire d'une admin sys sur le serveur HAProxy.

Le script

Pour celà j'ai concocter un petit script batch générique qui fait très bien le travail.

sudo mkdir /root/scripts & cd /root/scripts
vim /root/scripts/renew_all.sh

Le voici

#!/bin/bash

#Configuration variables
certbot_bin="/usr/bin/certbot"
haproxy_pem_path="/etc/haproxy/certs"
http_01_port='54321'
exp_limit=30

#Then, create domain.pem containing fullchain et privkey for haproxy
for domainconf in $(ls /etc/letsencrypt/renewal/); do
        domain=${domainconf%.conf}

        cert_file="${haproxy_pem_path}/${domain}.pem"
        exp=$(date -d "`openssl x509 -in $cert_file -text -noout|grep "Not After"|cut -c 25-`" +%s)
        datenow=$(date -d "now" +%s)
        days_exp=$(echo \( $exp - $datenow \) / 86400 |bc)

        if [ "$days_exp" -gt "$exp_limit" ] ; then
                echo "[${domain}] : The certificate is up to date, no need for renewal ($days_exp days left)."
                #exit 0;
        else
                echo "The certificate for $domain is about to expire soon. Starting Let's Encrypt (HAProxy:$http_01_port) renewal script..."
                $certbot_bin certonly --standalone --renew-by-default --http-01-port $http_01_port -d ${domain} -d www.${domain}
                cat /etc/letsencrypt/live/${domain}/fullchain.pem /etc/letsencrypt/live/${domain}/privkey.pem > ${haproxy_pem_path}/${domain}.pem
        fi
done

# At the end, reload haproxy
echo "$(date +%c) Reload haproxy"
/usr/sbin/service haproxy reload

Les deux seuls paramètres que vous pourriez vouloir changer sont :

  • http_01_port='54321'
  • exp_limit=30



A savoir, le port utiliser pour la génération des certificats, et la limite (en jours) à partir de laquelle vous souhaitez régénérer un certificat .

sudo chmod +x /root/scripts/renew_all.sh
sudo -s
crontab -e

On ajoute cette ligne dans la crontab ( afin de vérifier chaque jour les certificats à régénérer )

@daily /bin/bash /root/scripts/renew_all.sh 2>&1 | mail -s "[SSL Lindev] Vérification des certificats SSL HAProxy" admin@lindev.fr

Et voilà chaque jour, le script sera exécuté et vous recevrez un petit mail résumant le temps restant pour chaque certificat et potentiellement les logs de régénération s'il y en a eu.

Nouveau domaine à gérer

Imaginons que vous souhaitez gérer un autre nom de domaine, vous devrez la première fois créer le nouveau certificat.
Voici un petit script pour vous simplifier la vie.

sudo vim /root/script/new_cert.sh

le voici

#!/bin/bash

#Configuration variables
certbot_bin="/usr/bin/certbot"
haproxy_pem_path="/etc/haproxy/certs"
http_01_port='54321'
domain=$1

$certbot_bin certonly --standalone --renew-by-default --http-01-port $http_01_port -d ${domain} -d www.${domain}
cat /etc/letsencrypt/live/${domain}/fullchain.pem /etc/letsencrypt/live/${domain}/privkey.pem > ${haproxy_pem_path}/${domain}.pem

# At the end, reload haproxy
echo "$(date +%c) Reload haproxy"
service haproxy restart

On le rend exécutable

sudo chmod +x /root/scripts/new_cert.sh

A partir de là pour générer un nouveau certificat (qui sera par la suite automatiquement renouvelé), il vous suffit (en root) d'executer ce script comme ceci

cd /root/scripts
./new_cert.sh mon_nouveau_domaine.com

Et voilà , le certificat sera généré, renouvelé automatiquement et pris en charge par HAProxy .

Conclusion

Nous avons mis en place notre front (HAProxy) qui se charge de la partie SSL puis redirige les flus vers un ou plusieurs backends .
L'avantage de cette configuration et la simplicité de gestion des certificats, même avec plusieurs backends physiquement différents ( load balancing, différents services etc ... ).

Prochaine étape intercaler entre HAProxy et le backend, un serveur de cache ( Varnish ) .

Dans un prochain billet... N'hésitez pas à commenter.

Ch.

07 fév. 2016

Vagrant, environnement de développement unifié

Vagrant.png Je souhaite proposer aux différents développeurs d'un projet, un moyen simple d'avoir un environnement le plus proche possible du serveur de production, que ce soit au niveau de la distribution, mais également des versions des outils installés ( Php, Mysql MariaDb, MongoDb, python, uwsgi, etc ... ). Le but étant de mettre en place l'environnement en un minimum de temps possible, mais aussi de permettre aux développeurs de rester sur leur système d'exploitation préféré. (Linux Mac ou même Windows) pour développer.

Première approche

Peut être (certainement) dû à l'effet de mode, j'ai commencé mes tests avec Docker. Ce dernier permet ce genre de chose, mais je trouve la façon de faire un peu complexe ( Liaisons entre les conteneurs, maintenabilité de l’ensemble etc ) , juste pour avoir un environnement de dev ! Il est vrai que cette techno est vraiment intéressante, le partage de conteneurs avec les autres utilisateurs, le versionning grâce à l'union FS et tout ça sans exploser la conso d'espace disque.

Plus simple, vagrant

Puis un ami m'a parlé de Vagrant, une techno que je n'avais pas encore étudié plus que ça. Pour résumer, il n'y a rien de magique, c'est "juste" un écosystème de gestion de VMs , basé sur virtualbox, qui permet de créer/manager des VMs à partir de systèmes de bases disponibles sur le net ( catalogue Vagrant Boxes ) et surtout de provisionner ces VMs.

C'est là que ça devient intéressant, on a donc un système de gestion de VMs compatible Linux,Windows,Mac, permettant une gestion de VMs très efficace, start, stop, freeze, resume, reload etc ... mais surtout, vous permet de monter une VMs configurée selon vos souhaits et ce de plusieurs façons.

Testons avec un simple environnement LAMP

Je vais volontairement aller vite sur les options disponibles, la doc en ligne de Vagrant étant extrêmement clair, je ne vais pas la copier/coller ici

Commencez par installer Vagrant ( pas besoin d'explication pour cette étape triviale )

Système de base

Nous allons travailler sur une Debian Jessie . Commençons par créer un répertoire pour notre projet ( je le nomme lamp )

mkdir lamp && cd lamp
vagrant init debian/jessie64

Dans notre répertoire lamp, nous trouvons maintenant un fichier de configuration de notre environnement nommé Vagrantfile. Nous allons bientôt mettre les mains dedans .

Capture_d_e_cran_2016-02-13_a__14.53.05.png

Le téléchargement est terminé ? oui ? très bien lançons notre "machine" et allons faire un tour dedans .

Lancer la VM et tour du propriétaire

vagrant up

Une fois la machine lancée, prenons la main en ssh

vagrant ssh

Vous voilà connecté à notre machine. Le système est nu. Avez-vous remarqué au lancement de la vm, ces deux lignes :

==> default: Installing rsync to the VM...
==> default: Rsyncing folder: /Users/moi/lamp/ => /vagrant

Par défaut, vagrant synchronise le répertoire local ( dans notre cas /Users/moi/lamp/ ) avec le répertoire /vagrant présent à la racine du système de fichiers de la VM.
Nous pouvons bien entendu ajouter d'autres répertoires ( voir le fichier de configuration Vagrantfile ligne: config.vm.synced_folder "../data", "/vagrant_data" ).

Retournons sur notre machine hôte ( Cmd + D )

LAMP

Linux ( Ok ça c'est fait ), Apache ( à installer ), Mysql/MariaDB ( à installer ), Php ( à installer ).
Bon on sait ce qu'il nous reste à faire. Mettons les quelques lignes nécessaires à l'installation de ces derniers dans un script bash. Éditons donc dans le répertoire lamp, un fichier que nous nommerons bootstrap.sh

Voici le contenu:

#!/usr/bin/env bash

#Login par defaut : root et pwd : rootpass ( à modifier bien évidemment )
debconf-set-selections <<< 'mysql-server-5.5 mysql-server/root_password password rootpass'
debconf-set-selections <<< 'mysql-server-5.5 mysql-server/root_password_again password rootpass'

apt-get update
apt-get install -y apache2
apt-get install -y mysql-server
apt-get install -y php5 php5-mysql php-pear


if ! [ -L /var/www ]; then
  rm -rf /var/www
  ln -fs /vagrant /var/www
fi

Éditons ensuite le fichier Vagrantfile, et en dessous de la ligne config.vm.box = "debian/jessie64" ajouter :

config.vm.provision :shell, path: "bootstrap.sh"

Ne reste plus qu'à provisionner la VM

vagrant reload --provision

Capture_d_e_cran_2016-02-13_a__14.55.18.png

Vous voilà avec un lamp de base, mais comment communiquer facilement avec ?

Le réseau

Il y a plusieurs solutions selon votre besoin.

  • Natter un port de votre machine hôte vers la VM
  • Créer un bridge avec une des vos interfaces pour que la VM soit présente comme n'importe quel autre poste sur votre réseau local
  • Créer un réseau privé permettant à la machine hôte d’accéder à la VM , tout en restant inaccessible depuis l'extérieur pour les autres postes ( solution retenu dans mon cas ).

Éditons le fichier de configuration pour activer ce mode. dé-commenter/compléter cette ligne :

config.vm.network "private_network", ip: "192.168.33.10"

Relançons notre vm

vagrant reload

Testons notre serveur Apache, ouvrez un navigateur, et entrez l'ip de votre vm : http://192.168.33.10

Et là ... vous avez un magnifique "404 not found" !!!.
Normal, le vhost par défaut d'apache cherche ses sources dans le répertoire /var/www/html . et si vous avez bien observé, dans le fichier bootstrap.sh, nous avons ces lignes :

if ! [ -L /var/www ]; then
  rm -rf /var/www
  ln -fs /vagrant /var/www
fi

Qui a pour but de mettre le répertoire "vagrant" ( partagé entre l'hôte et la vm ) accessible ( via un lien symbolique ) vers /var/www . Il nous suffit donc de créer un répertoire nommé html dans notre répertoire de projet, lamp ( sur la machine hôte ).

Donc, sur notre machine hôte, dans notre répertoire lamp :

mkdir html && cd html
echo '<?php echo phpinfo();' > index.php

Relançons notre vm

vagrant reload

Maintenant allons rafraichir notre navigateur . Vous devriez avoir la belle page de phpinfo qui s'affiche . Capture_d_e_cran_2016-02-13_a__13.54.36.png

NFS

C'est magnifique, mais si vous ajoutez des fichiers depuis la machine hôte dans le répertoire html, ces derniers ne seront pas accessibles ( synchronisés ) sur la VM. Il faudra pour celà lancer la commande

vagrant rsync-auto

Pas très pratique. Je me suis donc tourné vers le protocole NFS qui est pris en charge en natif avec vagrant ( attention.. ne fonctionne pas avec Windows ).
Éditons notre fichier Vagrantfile et ajoutons ces quelques lignes avant de relancer notre vm

  config.vm.synced_folder ".", "/vagrant",
    :nfs => true

Relançons la VM

vagrant reload

Vagrant va vous demander le mot de passe sudo, afin de modifier pour le fichier /etc/exports.
Afin que le mot de passe ne soit pas demandé à chaque démarrage, vous pouvez soit:

  • Ajouter des règles dans le fichier de config sudo ou ...
  • Renseigner une bonne fois pour toute votre fichier exports et indiquer à vagrant qu'il n'a rien à faire . ( voir les options NFS ).

Conclusion

Voilà pour le premier tour d'horizon de Vagrant, nous avons dans nos main un système de gestion de VM bien ficelé, doté de nombreuses autres options, ( snapshots/restauration, share, ... ) je ne peux que vous conseiller d'aller faire un tour sur le site officiel pour découvrir les différentes options qui s'offrent à vous. Enfin, pour gérer vos environnements, je vous conseil de versionner votre projet ( dossier lamp dans notre exemple ) avec Git par exemple, car c'est grâce aux fichiers de ce répertoire que vous serez en mesure de remonter/partager une VM configurée à l'identique sans aucun effort et en un minimum de temps.

15 août 2013

Python Web: Setup Django + MongoDB

django.jpg

Setup Django + MongoDB

Je travaille actuellement sur un projet d'application Web industriel basé sur les technologies suivantes

  • Python ( avec le framework Django V1.5.2 )
  • MongoDB ( Pour son efficacité et flexibilité )

Deux technologies que j'affectionne particulièrement, tant par le coté administration ( Principalement pour mongodb ) que par le coté utilisation.

Le framework MongoDB est parfait pour un projet industriel relativement imposant, mais peut tout aussi bien l'être pour une petit site de quelques page ( bien que pour ce genre de micro projet, je préférerais utiliser le framework flask, ou si je souhaite changer un peu d'air, utiliser Node.js avec le framework express.js ).

Seul "problème", Django n’intègre pas en natif la gestion des bases de données NoSQL comme MongoDB. Heureusement, quelques outils permettent de profiter pleinement de Django et MongoDB ensemble, notamment avec l'utilisation de la librairie MongoEngine, basée sur pymongo

N'ayant pas toujours le temps de transcrire mes tutoriels, je vais mettre le lien de mon document GoogleDoc, qui se complète au fur et à mesure du temps , n'hésitez donc pas à le parcourir, et laisser des commentaires, me corriger...

Django First steps

Bonne lecture,

Ch.

20 oct. 2011

Django étape par étape [Apache2 et mod_wsgi]

logo_django.png
Comme précisé dans le précédent billet, j'aime utiliser un environnement aussi proche que possible à l'environnement de production, cela commence par le serveur web finalement utilisé, dans mon cas Apache.
Voyons comment configurer un Vhost pour gérer notre projet Django

Le programme

  1. -OnLine- Présentation et installation du framework et MysqlDB
  2. --> Configuration du serveur web Apache, liaison avec le projet
  3. -OnLine GDOC- Première application sous django ( urls.py, settings.py )
  4. -OnLine GDOC- Mise en place de Django-Debug-toolbar
  5. -OnLine GDOC- Protection CSRF , utilisation , Jquery et requetes AJAX
  6. -OffLine- Les formulaires, utilisation basique du paquet Django.forms
  7. -OffLine- Les models création, utilisation et synchronisation
  8. ... la suite en fonction de mon apprentissage personnel :)

N'ayant pas toujours le temps de transcrire mes tutoriels, je vais mettre le lien de mon document GoogleDoc, qui se complète au fur et à mesure du temps , n'hésitez donc pas à le parcourir, et laisser des commentaires, me corriger ...

Django First steps

Prérequis


Nous allons nous mettre en condition pour mener à bien cette étape qui finalement, vous allez le voir, sera assez rapide.
Je part du principe ou apache est installé avec les paquets par défaut de la distribution.
Pour prendre en charge un projet python, nous avons plusieurs pistes,

  • mod_python

Déprécié, je ne l'utiliserai donc pas

  • fastcgi ou sgi
  • mod_wsgi

C'est ce dernier mode que je vais détailler ici, bien que les autres soient viables et "comme le dit la documentation" plus performants dans certaines configurations, le mod_wsgi reste le mode conseillé par Django.

Rappel sur wsgi

wsgi est une interface entre le serveur HTTP et l'application Python.
Pour plus d'information sur le sujet je vous conseil le site officiel.

Mise en place

Au niveau de l'application

Pour permettre à notre application de tirer parti de wsgi, nous allons créer à la racine un répertoire nommé "apache", dans ce répertoire , nous allons créer un fichier nommé django.wsgi.
Voici le contenu du fichier "django.wsgi"

import os, sys

sys.path.append('/var/www')

os.environ['DJANGO_SETTINGS_MODULE'] = 'monprojet.settings'

import django.core.handlers.wsgi

_application = django.core.handlers.wsgi.WSGIHandler()

def application(environ, start_response):
    #environ['SCRIPT_NAME'] = '/'
    environ['PATH_INFO'] = environ['SCRIPT_NAME'] + environ['PATH_INFO']
    return _application(environ, start_response)

info.png Deux lignes sont à modifier selon votre projet, et son emplacement ( lignes 2 et 3 ).
Dans le précédent billet, nous avons créer le projet monprojet à l'emplacement /var/www

Niveau apache

Il nous suffit de configurer correctement notre Vhost en précisant quelques paramètres propres à wsgi.
Voici le vhost de notre projet nommé : monprojet et disponible à l'adresse http://monprojet.com

<VirtualHost *:80>
        ServerAdmin monemail@domaine.com
        ServerName  monpropjet.com
        ServerAlias www.monprojet.com

        DocumentRoot /var/www/monprojet/

        Alias /static/ /var/www/monprojet/static/
        Alias /uploads/ /secure_dir/uploads/

        WSGIDaemonProcess daemon-monprojet user=www-data group=www-data processes=1 maximum-requests=1 threads=1 inactivity-timeout=6
        WSGIProcessGroup daemon-monprojet
        WSGIScriptAlias / /var/www/monprojet/apache/django.wsgi

        <Directory /var/www/monprojet/apache>
                Order deny,allow
                Allow from all
        </Directory>

        <Location "/uploads/">
                SetHandler None
        </Location>

        ErrorLog /var/log/apache2/monprojet.error.log
        CustomLog /var/log/apache2/mystock.access.log combined

</VirtualHost>

Les fichiers "statiques" ( img,css,js,... ) seront servi directement par apache, à partir du moment ou les urls pointent vers /static/* , concernant /uploads/, comme son nom l'indique, pointe vers l'espace de stockage des éventuelles uploads des clients, il est conseillé de mettre hors d'atteinte les fichiers uploadés par les clients, et encore moins interprétables, d'ou le SetHandler None.

Pour le reste, apache passe le relais à WSGI, vous devrai certainement affiner les paramètres, tels que processes, maximum-requests threads ou inactivity-timeout, il y en a d'autres, et je vous laisse lire la doc pour ajouter/modifier des paramétrés à WSGIDaemonProcess

warning.pngAttention à mettre un nom de daemon différent à chaque vhost hébergeant un projet Django.
Veillez à adapter le Vhost à votre environnement ( directory, user et group )

Ne vous reste plus qu'à ré-démarrer votre serveur Apache ( apres avoir enregistré votre vhost, en site-enabled ou simplement Inclus dans httpd.conf ).

Conclusion

Voilà , notre environnement de développement est maintenant en place, nous allons pouvoir dans le prochain billet attaquer un peu le code, nous verrons l’organisation des "applications", la configuration de base et les templates partagés ect ..

11 oct. 2011

Django étape par étape [Installation Environnement]

logo_django.png
Voilà maintenant quelques temps que je voulais allier python et développement web, c'est aujourd'hui chose faite :) .

Après quelques recherches sur la toile, mon choix s'est finalement trouvé vers "django".
La documentation complète et claire, une communauté active ainsi que de nombreux exemples sont disponibles, du petit bout de code à l'application intégrable à votre projet.
Il faut bien évidemment prendre quelques nouvelles habitudes pour se sentir un minimum alaise, mais comme souvent avec des produits de cette qualités, la courbe de progression est rapide.

C'est par ces quelques billets que je vais tenter de vous aider à passer avec succès la mise en place et le développement basique d'un projet basé sur Django.
Les "pro" ou plutôt "djangoer's barbu" ne vont peut être pas trouver dans mes explications les "bests practices" qu'ils pratiquent quotidiennement, mais ces billets sont destinés à partager ma découverte et aider les débutants qui comme moi apprennent à utiliser ce superbe outil.
A tout lecteur, n'hésitez pas à laisser vos conseils, qui seront profitables à tous.

Le programme

  1. --> Présentation et installation du framework et MysqlDB
  2. -OnLine- Configuration du serveur web Apache, liaison avec le projet
  3. -OnLine GDOC- Première application sous django ( urls.py, settings.py )
  4. -OnLine GDOC- Mise en place de Django-Debug-toolbar
  5. -OnLine GDOC- Protection CSRF , utilisation , Jquery et requetes AJAX
  6. -OffLine- Les formulaires, utilisation basique du paquet Django.forms
  7. -OffLine- Les models création, utilisation et synchronisation
  8. ... la suite en fonction de mon apprentissage personnel :)

N'ayant pas toujours le temps de transcrire mes tutoriels, je vais mettre le lien de mon document GoogleDoc, qui se complète au fur et à mesure du temps , n'hésitez donc pas à le parcourir, et laisser des commentaires, me corriger ...

Django First steps

Système d’exploitation et python

Je travail sous mac et linux(Débian), et peu donc vous confirmer que les explications qui vont suivre sont tout à fait fonctionnelles sur ces deux systèmes ( je suppose que nos utilisateurs M$, n'auront aucun mal à s'adapter ).

python_logo_no_text.jpgConcernant Python, j'utilise pour mes développements la version 2.7 / 2.6 sous mac.
Je conseil tout de même à tout débutant de suivre les quatre pages de tutoriel officielles qui donnent déjà un bel aperçu de l'efficacité de l'outil.

Installation de Django

La version utilisée sera la toute dernière stable au moment ou j’écris ces lignes, à savoir la version de django 1.3

L'installation de Django est très simple, voyez par vous-même, en trois lignes, le Framework est prêt à vous rendre service.

Installation proprement dite

wget http://media.djangoproject.com/releases/1.3/Django-1.3.1.tar.gz
tar xzvf Django-1.3.1.tar.gz
cd  Django-1.3.1
sudo python setup.py install

Pour vérifier la disponibilité de django sur votre système, il vous suffit de lancer une console python, et d'importer le paquet django

Lancement de la console python:

(1:5)$ python
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

Testons l’importation de django:

>>> import django
>>> print django.get_version()
1.3

Installation de mysqldb

Mon premier projet django utilisera une base de données Mysql, il me faut donc installer l'API adéquate, MysqlDB.
Deux solutions, utiliser la version disponible dans les dépôts officiels de la distribution utilisée ( Débian Squeeze dans mon cas ), ou l'installer à partir des sources, dans les deux cas, il vous faut avoir les librairies de mysql-client, d'installées .
J'ai opté pour l'utilisation de la version dépôt pour débian, et la compilation des sources pour Mac.

Installation de mysqldb sous linux

 
apt-get install python-setuptools python-mysqldb

Nous voilà enfin prêt pour créer notre premier projet django. Dans mon exemple , je vais placer mon projet en suivant le chemin suivant /var/www

Initialisation du projet

Nous y voilà, les premières briques sont prêtes à être posées, Django nous offre un utilitaire permettant d'initialiser le projet de façon automatique... Puisque c'est automatique, profitons en, l'informaticien est par défaut fainéant ;) ( ce serai surtout stupide de faire à la main ce qui peut être fait automatiquement ).

django-admin.py

Je ne vais pas détailler toutes les fonctionnalités de cet utilitaire, par contre, je vous invite à parcourir la documentation officielle pour entrer dans les détails.

Initialiser le projet

cd /var/www 
django-admin.py startproject <mon projet> 

Regardons ce que cette commande magique à faite.

(1:8)$ tree monprojet/
monprojet/
├── __init__.py
├── manage.py
├── settings.py
└── urls.py

0 directories, 4 files

manage.py Le script manage.py, est un intermédiaire entre votre projet et django-admin.py, qui a pour but de nous simplifier la vie, en déclarant par exemple automatiquement le projet dans l’environnement python.
Nous utiliserons donc de façon plus régulière de dernier pour les tâches d'administration du projet.

settings.py Détaillé dans le tutoriel N° 3
La configuration global de votre projet, c'est dans ce fichier que nous allons définir le type de base de données utilisé, les applications installées au sein du projet, la définition de middleware, définition de context, template_context_processor nous verrons de quoi il s'agit plus tard, définition de variables de configuration, url des fichiers statiques, des templates ect ect ... Bref LE fichier de configuration de votre projet

url.py Détaillé dans le tutoriel N° 3
C'est à partir de là qu'une requête sera redirigée vers une "action". Nous verrons plus tard comment django gère les requêtes et les rediriges, comment l'on peut passer les paramètres "GET", passer des paramètres pas defaut, et bien plus encore, Django possède un système de "dispatche" très puissant et performant.

Fin de la première partie

Nous avons vu dans ce billet comment installer Django, MysqlDb, et comment initialiser un projet "vide", vous aller me dire il manque des choses .. oui effectivement, mais avant d'aller plus loin, il nous faut mettre en place un serveur HTTP pour tester notre code pendant son développement.
Django fourni un serveur HTTP pour le développement , à n'utiliser sous aucun prétexte pour la production .
Je suis habitué à développer dans un environnement le plus proche possible de l'environnement de production, c'est pourquoi j'ai décidé d'utiliser le serveur web Apache avec le mod_wsgi pour la suite de cette série de tutos sur Django.
Je ne vous parlerai donc pas du serveur Http embarqué, mais si vous voulez le tester, il vous suffit depuis la racine de votre projet d'entrer la commande suivante

python manage.py runserver

A chaque modification d'un fichier, celui-ci se relance pour prendre en compte les changements.

Dans le prochain Billet

Dans le prochain billet je vais donc détailler la configuration d'un vhost Apache, pour gérer notre projet Django, avec le mod-wsgi