Déploiement d’application web

Auteur(s) de l'article

Depuis plusieurs années nous nous intéressons à simplifier le déploiement de nouvelles versions (release) de nos applications web. Nous avons commencé par documenter les instructions à suivre sur un wiki ou un dans un fichier texte (le fameux README). Nous utilisons toujours cette méthode pour documenter l’installation d’un projet.

Déploiement « old school »

J’ai retrouvé dans nos archives (2007-2008) une procédure de déploiement:
1. Pré-requis (version PHP, Extensions, SGBD, ...)
2. Installation
2.1 Création de la base de données (et utilisateurs) (dump sql)
2.2 Importation des données initiales (dump sql)
2.3 Configuration de l'application (édition d'un fichier config.php)
2.4 Transfert des fichiers (via FTP)
2.5 Configuration du serveur HTTP (Apache)
3. Tests fonctionnels (liste des tâches à réaliser pour vérifier que tout est OK)
C’est fastidieux, non ?
… surtout si l’on doit répéter l’opération encore et encore.

Scripts Bash basé sur rsync et ssh

Par la suite, fatigué, nous avons écris des scripts BASH se basant sur rsync et SSH. Cela fonctionne relativement bien dans la majorité des cas.

Allez plus loin !

Très vite, nous nous sommes rendu compte que nos besoins dépassait largement le transfert de fichier. Nous voulions:
  • Mettre le site en maintenance (ou stopper les écritures)
  • Backup de la version actuelle
  • Mise à jour du schema de la base de données
  • Vider (ou Warm-up) le cache applicatif
  • Mettre le site en maintenance

Framework de déploiement

Pour répondre à ces besoins et faciliter la vie du développeur, il existe plusieurs outils libre en open-source. comme Capistrano (Ruby) ou Fabrik (Python).
Nous avons porté notre choix sur Capistrano principalement pour les raisons suivantes :
  • Des recettes existantes pour nos outils favoris (Symfony)
  • Le système de rollback intégré (pouvoir revenir à une version précédente en un clin d’oeil) est plutôt cool et te permet de rester détendu du slip lors d’une publication.

Capistrano

Capistrano est un framework de déploiement pour des applications web initialement écrites pour Ruby On Rails mais qui reste suffisamment souple et extensible pour être utilisé pour déployer d’autre types applications web. Dans notre cas, des applications basée sur PHP.

Pré-requis

  • Un accès SSH au serveur distant
  • Aimez ligne de commande
  • Savoir que Ruby n’est pas uniquement un jolie pierre flashy (bien que… 😉)

Installation

$ gem install capistrano

Déployer

« Push the red button »

$ cap deploy
Cool, non ?
Mais attention, avant de lancer le premier déploiement vous devez définir la configuration du projet (Capfileconfig.rb).

En gros, comment ça marche ?

La structure de répertoires créée sur le serveur distant va ressembler à ça:
.
|-- current -> ./releases/20130311184017
|-- releases
| |-- 20130301152536
| |-- 20130311180450
| `-- 20130311184017
`-- shared
|-- app
| |-- config
| `-- parameters.yml
|-- app
| |-- logs
| `-- production.log
`-- web
`-- uploads
Le répertoire releases contient les X dernières versions de l’application. current est un lien symbolique vers la dernière release.
shared contient les fichiers/dossiers qui sont partagé entre les différentes releases (config, logs, uploads)
A chaque fois que vous déployez, un nouveau répertoire va être créer sous le dossier « releases ». Le code de la nouvelle version de l’application est copié dans ce répertoire en fonction de la stratégie choisie. Par défaut via un checkout du code via git, subversion, mercurial, etc.
Il est possible de définir des fichiers (ou dossier) qui seront partagés entre les releases (configuration à la base de données, logs, uploads, …). Capistrano s’occupe de créer des liens symboliques vers chaque ressources partagées (exemple: /releases/20130311184017/app/config/parameters.yml -> /shared/app/config/parameters.yml)
Finalement, le lien symbolique « current » est mis à jour pour pointer vers la dernière « release ».
Vous devez configurer votre serveur web pour servir les fichiers à partir de /path/to/project/current/web.
La tâche suivante permet de créer cette structure de base avant le premier déploiement:
$ cap deploy:setup

Un bug inattendu, page blanche ? Rollback!

Cette structure basé sur des liens symboliques permet de switcher rapidement d’une release à une autre en cas de problème.
$ cap deploy:rollback
Permet de revenir à la version précédente, et vous laisse tout le temps pour corriger le bug.
Mega-cool, non ?

Configuration & recettes

Ce blog post est le premier d’une série sur nos recettes et configuration utilisées pour déployer nos applicaitons SymfonyDrupalMagento ou encore WordPress.
En attendant, voici un exemple de configuration utilisant les extensions railsless et
capistrano-ext.

Conclusion

Industrialiser ses déploiements offre beaucoup d’avantages, notamment:
  • Documentation par le code !
  • Standardisation de la procédure
  • Augmentation de la cadence des déploiements (tous les semaines, voir tous les jours)
  • Diminution du risque d’erreur humaine
  • Réduction des coûts (omoins de temps a déployer, plus à développer)
De plus, le fait d’automatiser la procédure nous force à créer des scripts de migrations (changement du schéma de base de données, migrations de données, …) ce qui est une bonne chose.