De zéro à Bipbip.js : pourquoi et comment nous avons développé notre outil de déploiement

Difficulté : | 13' Publié il y a 7 mois
Anciens utilisateurs de Capifony, nous avons choisi de développer notre propre solution de déploiement plutôt que d'utiliser Capistrano pour déployer nos applications Symfony. Nous avions une problématique liée au déploiement de nos projet. Cet article est un résumé de pourquoi nous avons choisi d'écrire Bipbip.js, notre outil de déploiement.

Synopsis

Agence web basée à Lyon, nous avons une forte expertise sur le framework Symfony. La majorité des projets déployés sont des Symfony 2 et désormais Symfony 3. Le déploiement de nos projets étaient dans un premier temps réalisés grâce Capifony (module basé sur Capistrano 2). Finalement, Baptiste s'est chargé de réinventer notre système de déploiement. Ainsi naquit bipbip.js.

Bipbip.js

Capistrano 3 vs Bipbip.js

Dans le cadre de l'amélioration continue de notre environnement de travail, nous avons décidé de moderniser nos processus de déploiements. Capifony était alors déprécié.

Évidemment, nous avons dans un premier temps cherché une solution du côté de son successeur Capistrano 3 qui se positionnait comme une suite logique. De plus, cela nous aurait permis de migrer en douceur nos configurations déjà en place.

Après de rapides recherches sur l'utilisation de la dernière version de Capistrano, nous avons constaté que la configuration à mettre en place avec le module Symfony ne correspondait pas à nos attentes (ces arguments étaient valables au moment de nos recherches, depuis ces arguments peuvent être caducs).

  • Peu de documentation ;
  • Peu d'aide de la communauté ;
  • Une capacité à customiser les étapes peu évidente ;
  • Un système de configuration difficile à lire et à écrire (le Ruby c'est forcément pas notre tasse de (thé|café)) ;
  • Des logs peu techniques qui ne nous aident pas à déboguer les erreurs.

Nous avons cherché des alternatives à Capistrano. Nous avons alors trouvé quelques prétendants mais le principal problème que nous avons relevé était que ces outils étaient prévus pour déployer des langages/frameworks spécifiques.

L'idée de développer un projet de zéro n'était pas une solution évidente au commencement car les risques étaient nombreux.

  • Devoir gérer un nouveau projet ;
  • Assurer un support et limiter les erreurs qui pourraient être critiques ;
  • Avoir besoin de fonctionnalités non présentes qui doivent alors être développées rapidement.

En contre-partie, développer une application nous permettait de mettre la main sur le déploiement de nos applications et également de mettre en place un système de configuration plus compréhensible.

Bipbip.js est ainsi né.

Bravo

Objectifs

Quand le développement de Bipbip.js a été lancé, j'avais une bonne idée de ce que cet outil devait être (et ne pas être).

Cet outil sera :

  • facile à appréhender ;
  • facile à customiser ;
  • facile à déboguer (pas de suppression de la release en erreur) ;
  • un projet accessible pour lequel chacun pourrait facilement contribuer ;
  • un outil qui simplifie vraiment la mise en place d'un déploiement et pas l'inverse.

À contrario, il ne sera pas :

  • lié à un langage particulier (déployer du PHP était notre objectif mais il devait être utilisable pour d'autres types de projet) ;
  • une boite "fourre tout" avec pleins d'options pour déployer en (S)FTP ou autre ;
  • un projet qui ne fait pas plus que ce qu'il doit faire (exécuter des commandes données dans un ordre défini).

Workflow

Lorsque nous utilisions Capifony, nous étions souvent déconcertés par les difficultés à appeler de simples commandes à un moment spécifique (comme générer nos assets avec Gulp plutôt qu'avec Assetic). Il nous fallait alors définir une commande dans un namespace et spécifier que celle-ci allait s'exécuter :before ou :after une autre commande.

Ce comportement ne nous convenait plus et il s'agissait du moment pour y remédier. Dans cette même idée, nous souhaitions un produit qui nous libèrait des modules pour tel ou tel framework. Bipbip.js devait nous laisser une liberté totale sur l'exécution des tâches que nous souhaitions.

Workflow de Bipbip.js

Arborescence

./your_project
|_ current
|_ releases
|_ shared

Comme dans Capistrano, un dossier releases permet de stocker les versions déployées. Un dossier shared permet de stocker les fichiers/dossiers partagés (uploads, configuration...). Pour finir, un lien symbolique current pointe vers la version en cours.

Spécification technique

Bipbip.js est développé en JavaScript (Node.js). Le langage Go a également été étudié. Nous avons privilégié Node.js pour sa facilité de prise en main, nous permettant de mettre l'accent plus rapidement sur les fonctionnalités.

Le seul protocole de transfert supporté est le SSH. Les connexions au(x) serveur(s) sont disponibles uniquement grâce à une clé SSH (pas de support de mot de passe).

La copie d'une release vers le(s) serveur(s) est réalisée grâce à rsync qui utilise lui même SSH.

Git est le seul outil de versionning supporté.

Pour finir, Bipbip.js est destiné aux serveurs Linux, ce qui représente une importante différence avec Capistrano (enfin presque).

Stratégie de déploiement

Écrire un outil était une chose, savoir comment il fonctionnerait était la seconde étape. Les réponses ont vite été trouvées. Bien que Capistrano ne nous satisfaisait pas dans sa configuration, sa customisation et sa réalisation nous aidaient : il reste un outil très bien réalisé. La stratégie de déploiement a donc fortement inspiré notre deployment tool.

Cela a d'ailleurs grandement facilité la migration de Capifony vers Bipbip.js.

Configuration

Contrairement à Capifony, Bipbip ne requiert qu'un unique fichier de configuration. La configuration est un fichier JavaScript (et non JSON).

Exemple :

exports.config = {
    default: {
        servers: [{
            user: "bipbip",
            host: "wanadev.fr",
            to: "/home/bipbipjs_is_swag"
        }],
        commands:  {
            local: [
                "echo foo", // première commande exécutée en local
                ["echo bar", "echo baz"], // deux commandes exécutées en local et en parallèle
            ],
            remote: [
                "echo foo" // commande exécutée sur les serveurs distants
            ],
            postDeploy: [
                "echo foo" // commande exécutée sur chaque serveur après la publication de la release
            ]
        },
        ignores: [
            ".git",
            ".gitignore",
            ".gitlab-ci.yml",
            "docker"
        ],
        shared: {
            files: [
                "config.json",
            ],
            folders: [
                "uploads"
            ]
        },
        releases: 3
    },
    <env>: {
    }
};

Conclusion

Après plusieurs mois d'utilisation et une migration en masse de tous les projets déployés chez nous, les objectifs fixés ont été atteints. L'investissement nous permet aujourd'hui de mieux maîtriser nos déploiements et de proposer Bipbip.js en Open-source à la communauté. Nous attendons avec impatience vos premiers retours !

Tags de l'article :

jenkins open source

Commentaires

  • Il y a 7 mois Florent : Répondre

    C'est une bonne idée. Mais pourquoi avoir recréé un outil quand il en existe des dizaines ? Je pense notamment à ansible qui a par exemple un module spécifique pour le déploiement http://docs.ansible.com/ansible/deploy_helper_module.html

    De plus un outil comme ansible gère déjà très bien le local et me ssh, permettant de déployer la même approche sur une dizaine de serveurs aussi rapidement que sur un seul. Rien n'empêche non plus de développer des propres modules ansible (en python).


  • Il y a 7 mois Baptiste : Répondre

    Bonjour Florent et désolé pour le temps de réponse, Forum PHP oblige ;-)

    Bipbip.js a été créé pour répondre aux soucis de déploiements que nous avons. D'autres outils existent déjà mais nous avons relevé les mêmes problèmes à savoir, peu de documentation, un système de configuration complexe et une faible communauté dans beaucoup de cas.

    Quant à Ansible, nous ne l'avions pas étudié à l'époque. Toutefois, je me suis posé question si Ansible était vraiment fait pour cela car il s'agit d'un logiciel idempotent alors que l'état de la machine changera à chaque fois qu'il y a un déploiement. Par contre, il est tout à fait vrai qu'Ansible aurait fortement facilité l'intégration du déploiement multi-serveurs et la gestion SSH.

    Pour résumé, Ansible aurait pu être une bonne base pour développer un module mais nous avons investit dans du code 100% géré pour nous ;-)