Dans cet article, je vais vous expliquer comment mettre en place un système de déploiement automatisé simple reposant sur le SCM Git. L’objectif est de pouvoir mettre à jour une application PHP simplement en effectuant un push sur le dépôt Git gérant cette application. 3 avantages pour cette méthode :
- Simple : une ligne de commande suffit pour mettre à jour l’application PHP
- Rapide : on ne transmet qu’un seul fichier
- Sûre : si un confit survient, le processus de mise à jour est arrêté et la copie de travail laissée intacte. De plus, l’application étant suivie par un outil de gestion de versions, on peut facilement effectuer un " rollback " si nécessaire
La solution proposée est simple à mettre en place. Si vous souhaitez un outil plus complet, je vous invite à regarder du côté de Capistrano proposant des fonctionnalités intéressantes. Ce dernier est toutefois relativement compliqué à mettre en place.
Configuration des dépôts sur le serveur web
Dans cet article, je suppose que votre serveur web utilise les fichier présent dans le dossier ~/www/.
Dans un premier temps, créez un dépôt intermédiaire destiné à recevoir les nouvelles versions, afin d’éviter les modifications directes sur la version de production.
cd ~
mkdir -p gitRepo/www.git
cd gitRepo/www.git
git init --bare
Rendez vous ensuite dans le dossier contenant les fichiers utilisés par votre serveur web et créez un nouveau dépôt destiné à gérer les sources de votre application.
## On créer le repository ##
cd ~/www
git init
git remote add origin ../gitRepo/www.git
## On crée le premier fichier ##
echo 'Hello World!' > index.html
git add .
git commit -m "Initial Import"
## On va utiliser la branche "prod" donc on checkout cette branche
git checkout -b prod
## Ensuite on envoie cette branche au dépôt intermédiaire ##
git push origin prod
Configurez maintenant le dépôt intermédiaire de manière a ce qu'il mette à jour la version de travail lorsque la branche de production est modifiée.
cd ~/gitRepo/www.git/hooks
nano post-receive
#!/bin/bash
#hook/post-receive
#CONFIG
PRODDIR="www"
read oldrev newrev refname
if [ $refname = "refs/heads/prod" ]; then
echo "===== DEPLOYING APP ====="
unset GIT_DIR
cd ~
cd $PRODDIR
git pull --ff-only origin prod
echo $?
echo "====== OK ====="
else
echo "Warning Commit not deployed, please use prod branch"
fi
Ce hook va mettre à jour automatiquement la copie de travail (~/www/) lorsque la branche de production est modifiée. Cependant, ce simple hook ne suffit pas, car si un fichier est modifié, la commande git pull ne peut être exécutée. Pour cela, ajoutez un second hook chargé de commiter les éventuelles modifications effectuées par l’application elle-même.
nano pre-receive
#!/bin/bash
#hook/pre-receive
#CONFIG
PRODDIR="www"
read oldrev newrev refname
if [ $refname = "refs/heads/prod" ]; then
echo "===== UPDATE REPOSITORY ====="
unset GIT_DIR
cd ~
cd $PRODDIR
git add .
git commit -m "Auto Commit"
echo "====== OK ====="
else
echo "Warning Commit not deployed, please use prod branch"
fi
Attention toutefois. Git utilise les hooks mis en place uniquement si leurs autorisations le permet.
## On modifie les autorisations sur les hooks
chmod +x post-receive pre-receive
Configuration du projet Local
cd /path/to/your/workspace
git clone [user]@[yourdomain]:gitRepo/www.git
cd www
## eg : git clone [email protected]:gitRepo/www.git
## on checkout la branche "prod"
git checkout prod
Changez maintenant le fichier index.html et mettez à jour la version de production en utilisant notre chaîne de déploiement automatisée mise en place précédemment.
nano index.html
## vous pouvez mettre ce que vous voulez dans le fichier index.html
## eg : Hello From Git
git add .
git commit -m "Test de déploiement automatique"
## La modification à été enregistrée en locale il faut maintenant
## la transmetre à " origin " afin de mettre à jour la version de
## production
git push origin prod
La commande git push va transmettre vos modifications au dépôt intermédiaire et mettre à jour la version de production en effectuant un merge par l'intermédiaire des hooks. Si un conflit survient, le processus est annulé et la version de travail n’est pas modifiée afin d’assurer la continuité du service.
Pour aller plus loin
Protéger le dossier .git
Le dossier .git est probablement accessible depuis votre site. Pour des raisons de sécurité, il est indispensable de bloquer l’accès à ce dossier en HTTP. En effet, il contient toutes les sources de votre application ainsi que leurs différentes révisions. Si vous utilisez Apache, vous pouvez ajouter le code suivant dans votre VHost ou dans un fichier .htaccess.
<Directory .git>
order allow,deny
deny from all
</Directory>
<Files .gitignore>
order allow,deny
deny from all
</Files>
Le fichier .gitignore
Un dernier point : il faut aussi penser à exclure les fichiers de fonctionnement de votre application comme les dossiers de cache ou les dossiers d’upload. Le dépôt Git ne doit gérer que les sources de votre application que vous modifiez et non ceux modifiés par l’application elle même. Cela évite au maximum les conflits.