Automatiser la mise en production d'un site web avec Git

avatar-Nicolas Nicolas
Publié le

En informatique, la gestion de configuration permet de développer sereinement (gestion des versions, mise en évidence des différences, rollback, ...). Historiquement, SVN était le leader mais depuis quelques temps, il est challengé (et dépassé) par Git.

Aujourd'hui, regardons comment optimiser le workflow du développement jusqu'à la mise en production avec Git.

Workflow Git

Préambule

Dans ce qui suit, nous allons considérer la situation suivante :

  • le développement est fait dans /var/www/project depuis plusieurs postes de travail,
  • le serveur de production s'appelle server, a pour adresse IP 10.0.0.2 et l'utilisateur s'appelle admin (original, hein).

Transformer l'espace de travail développeur en dépôt local

Sur un des postes de travail où l'ensemble des fichiers du site est disponible, nous allons initialiser le dépôt Git :

cd /var/www/project/
git init
git add *
git rm --cached .buildpath .project
git commit -m 'Version initiale'

Comme vous pouvez le voir, la syntaxe est simple : git "commande".

On commence par créer le dépôt (init), puis on ajoute des fichiers présents (add) ou on les enlève (rm) dans l'index. Enfin on enregistre l'index via un commit (équivalent d'un instantané de l'index que l'on pourra exporter, comparer, appliquer).

Pour exclure les fichiers liés à l'outil de développement, on peut jouer sur l'argument de git add ou les retirer de l'indexation via git rm (l'option --cached indique de désindexer le fichier).

L'option -m de commit permet d'indiquer un message lié.

Au passage, ici c'est la version en ligne de commande, mais plein d'outils cools permettent de faire le boulot avec une interface graphique. Un plugin Eclipse existe également...

Créer le dépôt de référence

Le dépôt de référence permet de synchroniser les dépôts des différents contributeurs. Contrairement aux dépôts locaux, les fichiers indexés n'ont pas d'existence physique. On crée le dossier sur le serveur :

mkdir /var/git/project

Depuis le poste de développement, on clone le dépôt local vers le serveur, l'option --bare indique qu'il s'agit d'un dépôt de référence :

git clone --bare /var/www/project ssh://admin@10.0.0.2/var/git/project/

Créer le dépôt local de production

Maintenant que le dépôt de référence est créé sur le serveur, il faut créer le répertoire de travail dans le répertoire Apache. Dans le cas (plus que probable) où vous utiliseriez déjà ce répertoire de travail, il faut le sauvegarder et le vider avant de le synchroniser au dépôt de référence :

mkdir ~/backup/www
mv /var/www/project/* ~/backup/www
git clone /var/git/project/ /var/www/project/

That's all. Notre répertoire Apache est désormais lié avec le dépôt central.

Déployer une mise à jour

Après avoir corrigé un bug-qu'en-est-pas-un ou ajouté une feature-trop-géniale, il faut mettre à jour dépôt de référence le sur le serveur ; pour cela du poste de développement, on commite les changements et on les pousse (push) vers le dépôt :

git add monFichierBiduleModifie
git commit -m 'Fix du fichier bidule'
git push ssh://admin@10.0.0.2/var/git/project/ master

Puis, il faut déployer du dépôt de référence vers le dépôt Apache, via la commande pull (depuis le serveur) :

cd /var/www/project/
git pull /var/git/project master

Et voila. L'argument master indique la branche. Je ne m'attarde pas dessus pour l'instant, mais n'hésitez pas à rechercher sur le net (c'est une des grandes forces des outils de versioning).

Sécuriser Apache

Attention, Git créé ses propres fichiers et répertoires au sein de votre répertoire, pour en empêcher l'accès (ce qui pourrait être ennuyeux), il suffit d'ajouter ces lignes au fichier situé dans /etc/apache2/conf.d/security :

<DirectoryMatch "/\.git"> 
        Deny from all 
        Satisfy all 
</DirectoryMatch>

Automatiser le déploiement

Tout ça c'est bien joli mais pour l'instant c'est plus compliqué qu'avant de mettre en production mes développements...

Oui. Mais c'est contrôlé. Et là où cela devient intéressant pour toi petit fainéant, c'est quand on profite des automatisme de Git. En effet à chaque événement (commit, push, ...), on peut associer des commandes ; dans le jargon, cela s'appelle un hook.

Ici, on va vouloir automatiser la séquence de mise à jour d'un site web (arrêt des processus Apache, mise à jour des fichiers, attribution des droits/propriétés et enfin redémarrage Apache) avec le hook post-merge :

nano /var/www/project/.git/hooks/post-merge

Saisir :

#!/bin/bash

owner="www-data"
path="/var/www/project/"
sudo service apache2 graceful-stop &&
echo -n "Setting working directory to $path..." &&
cd $path &&
echo " done" &&
echo -n "Changing ownership to $owner..." &&
sudo chown www-data:www-data * -R &&
echo " done" &&
sudo service apache2 start

On peut ajouter autant de commandes que l'on souhaite (faire un back-up des fichiers / de la base de données, effectuer des mises à jour de paquets, envoyer un mail à l'admin...).