Apprendre encore un nouvel outil, c’est du temps et de l’énergie. Du coup j’ai longtemps ignoré l’outil automatique de déploiement fabric.
On vit très bien sans, mais un jour, après avoir chassé un bug des heures qui n’était dû qu’à une erreur de ma part sur un process répétitif et ennuyeux de mise en ligne, je me suis motivé. Bonne surprise, ça m’a pris 30 minutes. Et avec cet article, ça vous en prendra 15.
Avant
Fabric est un outil qui vous permet d’écrire, en Python, un script de déploiement ; c’est à dire d’automatiser la mise en ligne d’une nouvelle version de votre site.
Comme ça, ça n’a pas l’air d’être quelque chose qu’on utilise souvent, mais pourtant, quand vous corrigez un simple bug dans une requête AJAX sur un projet Django sauvegardé dans Git, voilà ce que vous devez faire:
git pull remote branch
(pour s’assurer que personne n’a modifié le code entre temps)git push remote branch
(pour sauvegarder votre code tout frais)ssh user@host
(pour aller sur le serveur distant)cd /path/to/project
workon virtualenv
./manage.py collectstatic
(pour que le nouveau fichier Javascript soit mis en ligne)supervisorctl -c settings/prod_supervisor.ini restart all
(pour redémarrer les workers et qu’ils prennent en compte les modifications du code Python)
Après
Comme d’hab, on commence par un coup de pip:
pip install fabric |
Et dans un fichier fabfile.py
à la racine de votre projet en local:
from fabric.api import local, run, cd, env, prefix REMOTE_WORKING_DIR = '/path/to/project' env.hosts = ['siteweb.com'] env.user = 'username' def push(branch='master', remote='origin', runlocal=True): if runlocal: # lance la commande en local local("git push %s %s" % (remote, branch)) else: # lance la commande sur les serveurs de la liste eng.hosts run("git push %s %s" % (remote, branch)) def pull(branch='master', remote='origin', runlocal=True): if runlocal: local("git pull %s %s" % (remote, branch)) else: run("git pull %s %s" % (remote, branch)) def sync(branch='master', remote='origin', runlocal=True): pull(branch, remote, runlocal) push(branch, remote, runlocal) def deploy(branch='master', remote='origin'): # execute toutes les commandes dans ce dossier with cd(REMOTE_WORKING_DIR): # excute toutes les commandes avec celle-ci avant with prefix('workon virtualenv'): pull(branch, remote, False) run("./manage.py collectstatic --noinput") run("supervisorctl -c settings/prod_supervisor.ini restart all") |
Et voilà du temps de sauvé, et des erreurs évitées pour un investissement vraiment minimal.
Synchroniser son code avec le reste de l’équipe: fab sync
Déployer le code en production: fab deploy
Les deux: fab sync deploy
Et ce n’est qu’une intro. On peut faire des choses biens plus avancées, notamment gérer plusieurs type de déploiements, de serveurs, etc.
Notez qu’on pourrait faire le faire en bash sans avoir à installer fabric, mais un script bash, c’est tellement laborieux à faire évoluer…
Attention pour que supervisor prenne en compte les modifs faite dans le fichier ini il faut faire un reload et non pas restart, je viens d’en faire l’expérience et ça m’a prix 1 heure à comprendre pourquoi !!!
Ouai d’ailleurs faudra faire un article sur supervisor :-)
En résumé:
– restart c’est pour redémarrer les services que gère supervisor;
– reload c’est pour recharger les paramètres de supervisor.
C’est sympa tout ça …
Et comment réagi le script si y’a une fusion à faire ? :)
Une fusion ?
Je vais imaginer que tu veux dire un merge. Mais il y a pas de merge à faire en prod, les merges sont toujours faits sur les machines en local. On push en prod uniquement des branches stables, sauf grosse envie de suicide pressante.
Fabric 2 est sorti, les gros, et il est totalement différent. Faut publier un nouvel article !
La nouvelle version a l’air super chouette en plus.