Déployer une application Django avec Capistrano

Chez O2Sources on aime tout ce qui permet d’améliorer la productivité. Et si en prime ça permet d’éviter des erreurs, on adore !
Malheureusement jusqu’à maintenant, nous déployions toutes nos applications « à la main », en FTP.
Mais grâce à Capistrano, nous remédions maintenant à cela en automatisant le déploiement de nos applications, afin de gagner du temps et surtout, d’éviter les erreurs ou les oublis.

Capistrano est un outil permettant d’automatiser le déploiement des applications développé en Ruby.
Mais il est utilisable avec toutes vos applications. Qu’elles soient développées en Ruby, en PHP, en Python et même, si vous êtes un peu fou, en Java.
Dans l’exemple que je vais donner ci-dessous, l’application est développée en Python avec Django. Et nous avions une problématique majeure : nous désirons pouvoir déployer sur le serveur de développement et/ou sur le serveur de production sans avoir deux tâches différentes (afin d’être DRY évidemment).

Dans un dossier nommé deployment à la base de notre application, j’ai créé deux fichiers.
deploy
Il s’agit d’un script bash, qui permettra d’exécuter le processus sans avoir à taper « cap … ».
En voici le contenu.
#!/bin/bash
ENV=$1 cap deploy -f deployment/deploy.rb

Vous pouvez noter que avant d’exécuter le script, je définis une variable d’environnement à la valeur du premier argument passé en paramètres.
Cela nous permettra de choisir si nous désirons pousser en développement ou en production.

Puis un fichier deploy.rb.
Vous pouvez en voir le contenu complet. Mais je vais également le détailler dans la suite de cet article.

Nous définissons plusieurs valeurs de configuration.
set :deploy_to, {'dev' => '/chemin/vers/le/site/en/developpement', 'prod' => '/chemin/vers/le/site/en/production'}
set :domain, {'dev' => 'host.developpement', 'prod' => 'host.production'}

La première variable contient le chemin de notre application, en développement et en production.
Le second contient les hosts de nos serveurs de développement et de production.

Puis nous définissons le serveur sur lequel nous voulons déployer.
ENV['ENV'] = 'dev' if domain[ENV['ENV']].nil?
role :web, domain[ENV['ENV']], :master => true

Si le paramètre « ENV » est à la valeur « prod », nous déployons en production. Sinon, nous déployons en développement.

Ainsi pour déployer en développement, vous n’aurez qu’à appeller votre script bash :
deployment/deploy
Et en production, il faudra préciser le paramètre.
deployment/deploy prod

Notre tâche capistrano contient ensuite les directives de déploiement.
La tâche deploy:default est appellée automatiquement. Elle fait un svn update, mettant ainsi à jour les fichiers de l’application.
desc "Updating the repository files in " + ENV['ENV'] + " environment"
task :default do
  stream "cd #{deploy_to[ENV['ENV']]}; svn update"
end

Nous avons ensuite une seconde tâche qui supprime tous les fichiers .pyc de notre application, afin d’éviter un quelconque problème de cache avec ceux-ci (ils sont générés automatiquement par Python).
desc "Remove *.pyc files"
task :delpyc do
  stream 'cd ' + deploy_to[ENV['ENV']] + ';find . -type f -name "*.pyc" -exec rm -fv {} ;'
end

Puis nous mettons à jour la base de données de notre application en faisant un syncdb.
desc "Make sure database is in sync with models"
task :syncdb do
  stream "cd #{deploy_to[ENV['ENV']]}; python manage.py syncdb"
end

Et enfin, puisque c’est un projet Django, il faut, afin que les modifications soient prises en compte, recharger Apache.
desc "We reload apache"
task :restart do
  stream "/etc/init.d/apache2 reload"
end

Nous avons maintenant défini nos tâches. Et comme dit précédemment, la tâche default est exécutée automatiquement.
Mais il faut tout de même définir l’ordre d’exécution des tâches. C’est la que viennent les instructions « after ».
after 'deploy', 'deploy:delpyc'
after 'deploy:delpyc', 'deploy:syncdb'
after 'deploy:syncdb', 'deploy:restart'

Notre tâche Capistrano fera donc, dans l’ordre :

  1. Un SVN update afin de récupérer la dernière version du projet
  2. Une suppression de tous les fichiers .pyc
  3. Une remise à jour de la base de données
  4. Un rechargement du serveur

Pour rappel, vous pouvez voir la tâche complète et colorisée sur github.

Votre application est à jour. Ici, ça prends 2 minutes chrono. Et on est sur que ça fonctionne (et si ça ne fonctionne pas quand même, cela nous prévient) 🙂
Et vous, vous déployez vos applications comment ?

3 Commentaires

  1. ça à l’air très sympa ce petit utilitaire, ça me rappelle Fabric qui lui est en python.

    Pour ce qui est du déploiement, ça dépend de la taille des projets.

    Dans le cas d’un projet de petite taille un Tag de versioning + zc.buildout suffisent.

    Dans le cas inverse, j’utilise fabric qui crée un virtualenv afin d’enfermer un projet avec son propre exécutable python, exécute un setup.py pour installer le projet et lance pip pour les dépendances.

  2. Coucou! Et concernant l’envoi sur différents serveurs (test, prod etc) – y’a une extension sympatoche ici: http://www.capify.org/index.php/Deploying_to_Multiple_Stages

    Capistrano rulez!

  3. merci pour l’article cependant je prefere une solution web comme http://hosting.djangofoo.com

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *