Dans ma quête pour trouver une solution de déploiement automatique pour un site Web construit avec Grav, j'ai déjà établi que le plugin Grav git-sync ne répondait pas exactement à mes besoins. J'ai fait beaucoup de recherches depuis et je suis surpris de voir très peu de solutions sont disponibles, pas seulement pour Grav, mais pour les scripts post-commit et Webhooks en général.

Ce dont j'ai besoin, en gros, c'est de mettre à jour les fichiers sur les serveurs de production chaque fois qu'un nouveau commit est envoyé à GitHub:

Cela semble facile, car GitHub fournit des Webhooks pour envoyer un ping au serveur de production. Nous avons maintenant besoin d’un script de déploiement pour que notre application soit automatiquement déployée sur le serveur de production. Ce script de déploiement, dans le cas de Grav, devra simplement effectuer git pull et bin/grav clear-cache.

En réalité, vous avez besoin d'une app sur votre serveur pour recevoir le hook. De plus, ce noeud doit être accessible via une URL publique. C’est là que ça se complique, car il n’ya pas beaucoup de documentation ou d'app "tout en un" pour gérer cela.

Candidats potentiels

Le résultat le plus populaire lors d'une recherche Google pour une solution de déploiement est un dépôt git vide ("git bare repository") et un script post-receive sur le serveur de production. Cependant, bien que cette méthode soit la plus simple à implémenter, elle n'est pas automatique et ne peut pas être appelée directement par l'API GitHub Webhook. La seule façon de procéder de manière automatisée consiste à utiliser Travis CI pour envoyer le message au serveur de production après un test réussi.

D'autres résultats populaires sont soit vieux de 6 ans, n'offre qu'un support de base pour les scripts, offre seulement 1 site gratuit, offre un essai gratuit limité à 10 jours seulement, contient une énorme vulnérabilité de sécurité, semble excessivement compliqué, n'est qu'un tas de code "spaghetti" ou ne gère pas l'URL publique. Un projet était proche, mais il contient une interface utilisateur qui n'a pas l'air trop sûr au premier coup d'oeil.

La documentation de Github pointe vers Sinatra, une application Ruby utilisé pour créer rapidement des applications Web. Malheureusement, Sinatra est davantage orienté vers une utilisation locale, et non comme un deamon à installer sur un serveur de production.

Cela signifie qu'il y a un besoin pour une nouvelle solution de déploiement auto-hébergée. Ou pas ?

Écrire ma propre application

À ce stade, j'ai envisagé de créer ma propre application de déploiement. La question qui tue : qu'est-ce qui fait une bonne application de déploiement? Comment ça marche? Et à quoi cela ressemblerait-il si je l'écrivais? Faisons une liste:

  1. Écrit en PHP (plus rapide et plus facile à coder pour moi);
  2. Configuration facile via Composer, globalement ou par projet;
  3. Pas d'interface utilisateur. Le seul point accessible publiquement est l'URL pour lancer le script. Une application CLI est parfaite, question de sécurité et est plus facile à utiliser;
  4. URL publique pour la réception des Webhook, en dehors du dépôt git que nous souhaitons déployer pour une sécurité accrue;
  5. Utilisation des clés SSH, pas de mot de passe ni de jeton enregistré;
  6. Peut être intégré à une application existante via Composer, en utilisant vendor/bin/post-receive;
  7. Peut gérer les autorisations du serveur, tout en étant sécurisé (Utilisation de sudo sur une commande si nécessaire);
  8. Prise en charge de Grav, mais aussi d’autres framework;
  9. Prise en charge des Webhooks GitHub, tout en étant modulaire pour pouvoir s'intégrer à d’autres fournisseurs (BitBucket, etc.);
  10. Configuration sauvegardée dans des fichiers locaux. Utilisé dans une application existante, la config peut être stocké dans un fichier du genre .deployment;

Et voilà. Une application en ligne de commande, écrite avec le merveilleux Console Component de Symfony et capable de déployer notre code, avec une URL publique pour gérer la demande de hook de réception !

Mais attendez, quelque chose cloche. Si cette application peut être chargée par Composer dans un projet existant, comment peut-elle gérer l'URL public? Même si notre nouvelle app est chargé globalement, cela nécessite toujours une configuration supplémentaire dans Apache / Nginx. Peut-être que l’utilisation de la commande create-project de Composer pourrait être utile?

Ou peut-être que cette liste, le concept même d'un script de déploiement et ma perception de ce que c'est... est erroné...?

C'est un travail d'équipe

Plus je réfléchis à cette question et plus je fais de recherches, plus je réalise que ma perception de déploiement est erroné. Le concept d'un script de déploiement ne peut pas être à la fois capable de gérer l'URL publique pour le hook.

En regardant de plus près la liste, une chose devient évidente: un script de déploiement ne pourra jamais satisfaire les points de la liste, car certains de ces points ne sont pas compatibles les uns avec les autres!

Nous ne pouvons pas avoir l'URL publique gérée en dehors du code que nous souhaitons déployer, et avoir toujours le script de déploiement à l'intérieur en même temps! Pour cette partie, il n’y a pas d’autres solution: nous avons besoin d’un vhost Apache / Nginx dédié. La seule autre manière pour un service externe (GitHub) d’envoyer une requête (ping) à notre serveur serait avec une connexion SSH. Cela pourrait techniquement être fait en utilisant un service tel que Travis. Cependant, même si nous finissons par utiliser un service tel que Travis pour envoyer une requête ping à notre serveur de production, nous avons toujours besoin d'un script robuste pour gérer la procédure de déploiement une fois le ping reçu...

Bref, ça ne signifie seulement qu'une chose. Ma perception était erronée. C'est un travail d'équipe qui nécessite deux parties: Le script de déploiement et l'url publique:

Maintenant que nous avons établi ceci, certains candidats potentiels commencent à faire du sens. Peut-être que certains d'entre eux pourraient être utiles après tout...

Le script de déploiement : Deployer

Ici, ce n'est pas très compliqué. L'application Deployer est littéralement A deployment tool for PHP (un outil de déploiement pour PHP).

Ma première pensée quand je suis tombé sur cette application était qu'elle ne pouvait pas gérer l'URL publique. En effet, Deployer doit être exécuté à partir d'une machine de déploiement (votre ordinateur), et non du serveur de production lui-même. Mais je ne pense pas que ce serait trop compliqué de faire en sorte que le serveur de production se déploie lui-même. Ce faisant, nous allons essentiellement tout exécuter sur le même ordinateur (sauf si vous avez un serveur de déploiement dédié, ce qui n’est pas mon cas).

Bien sûr, nous risquons maintenant entrer dans une boucle infinie: comment déployer notre script de déploiement? Je pense qu'en ajoutant votre script de déploiement spécifique au projet dans le répertoire git du projet lui-même, cela devrait être correct. La seule chose dont nous avons besoin maintenant est quelque chose pour déclencher la construction.

Gestion de l'URL publique : Webhook & Travis

Celui-ci est un peu plus compliqué. Il y a Webhook, un outil écrit en Go, qui permet de créer facilement des points de terminaison HTTP (hook) sur un serveur. D'un côté, Webhook demande d'installer quelque chose sur le serveur (ce qui n'est pas un gros problème avec un VPS), mais, selon leur fichier Readme, il doti être exécuté manuellement et écouter sur un port non standard. Cela pourrait être un problème, mais peut probablement être résolu avec le Mod Proxy d'Apache (comme nous aurons quand même besoin d'un vhost dédié).

Un autre moyen de déclencher notre script de déploiement serait d’utiliser Travis CI. Travis offre quelques avantages. Par exemple, on peut déclencher un déploiement qu'après un build ou des tests réussis. Il ne requière pas nécessairement une URL publique et de Webhook, donc pas non plus de serveur Apache / Nginx Vhost dédié. Par contre, Travis nécessiterait un accès SSH à notre serveur de production.

Je pense qu'en fin de compte, cela est vraiment du cas par cas. Pour Grav, il n’y a pas de build ou de tests, donc nous n’avons généralement pas Travis prêt è l'emploie. Pour les applications plus complexes, par exemple une application créée avec UserFrosting, Travis est déjà opérationnel dans mon cas. Par conséquent, l'ajout du déploiement aux instructions de Travis pourrait être préférable, on est sûr de ne pas déployer de mauvais code si un test échoue.

Mais une chose est sûre: Webhook ou Travis, ils devront travailler avec Deployer pour arriver à notre fin. Voici donc mon plan à l'heure actuelle :

Conclusion

Une chose est sûre. Ce sujet n'est pas très bien documenté. La plupart des références que j'ai trouvées expliquent Deployer ou Webhook. Le déploiement automatique ne semble pas être un sujet populaire, probablement parce que vous devez avoir confiance en votre code pour ne pas planter à chaque commit (C'est pour cela qu'on utilise des tests automatisés, n'est-ce pas?). C'est peut-être aussi parce qu'il n'y a pas de solution universelle...

Depuis que nous nous sommes rendus compte que nous n'avions pas déployé la documentation sur le serveur de production depuis six mois avec l'équipe de UserFrosting, je pense que le déploiement automatisé est une chose sur laquelle nous devrions tous nous pencher. Heureusement, nous avons maintenant des outils qui peuvent nous rendre la vie plus facile. Fini l'époque du FTP! Et si Deployer se révèle digne de sa réputation, je pense que l'époque du déploiement manuel sur le serveur de production, en le connectant via SSH, sera bientôt révolue, enfin pour moi.

Fait amusant, ce n'est pas la première fois que j'expérimente avec le déploiement automatisé. Lorsque je travaillais sur SimpsonsCity.com il y a quelques années (vers 2012-2013?), j'avais un script PHP un peu pêle-mêle, très public (et potentiellement très non sécurisé) qui gérait la procédure de déploiement. Naviguez vers une URL, entrez votre mot de passe Htpasswd, et vous pouviez voir l'intégralité du git clone et ainsi de suite exécuté sous vos yeux. Aie aie aie... C'est drôle de voir que le même problème est toujours présent aujourd'hui, mais nous avons maintenant plus d'outils pour le gérer (et j'ai aussi plus d'expérience) sans avoir de solution définitive.

Bref, dans les prochains jours, je testerai à la fois Deployer et Webhook et je fais m'assurer de rédiger un guide définitif une fois que tout sera installé!

Références

Article précédent Article suivant