Comme vous pouvez le voir, ce site utilise le CMS Ghost. De plus, j'utilise un thème que je modifie ponctuellement en fonction de mes besoins, comme par exemple pour ajouter le multi-auteur qui n'était pas actif nativement.

Néanmoins, le défaut est que Ghost nécessite à chaque fois de redéployer le thème via le backoffice. Il faut de plus le compresser avec un nom unique à chaque fois.

Rien d'énormément bloquant, sauf que lorsqu'on travaille sur certaines améliorations, les allers-retours pour les tests peuvent être nombreux.

J'ai donc décidé de mettre en place un petit déploiement automatisé en exploitant CircleCI.

CircleCI - Outil de CI en mode SaaS

CircleCI est outil de CI qui fonctionne en mode SaaS, il permet d’exécuter des workflows de travail afin de construire des applications ou les déployer.

CircleCI peut se connecter nativement à GitHub/BitBucket et réagir lors de certains événements à l'aide de webhooks. Il existe un niveau d'utilisation gratuit, limité à une tâche en parallèle et 2500 crédits hebdomadaire (ce qui correspond à 250 minutes sur des machines medium)

Dans mon cas d'utilisation, je vais déclencher un déploiement sur mon serveur de test à chaque commit sur la branche "testing" sur GitHub, et un déploiement sur mon serveur de production à chaque commit sur la branche "master".

L'utilisation de containers permet d'avoir des exécutions d'à peine quelques secondes, ce qui permet d'utiliser pleinement la solution gratuite.

Préparation préalable

Préparation d'une image Docker

Comme je l'ai indiqué précédemment, CircleCI utilise des images dockers (entre autre). Il en existe un certain nombre fournies directement par CircleCI. Néanmoins, dans mon cas, j'ai 3 sites distinct à gérer, et je veux avoir le moins possible de fichiers en mode copier/coller d'un projet à un autre.

J'ai donc choisi de construire ma propre image docker, que j'ai publié sur DockerHub.

Vous pouvez trouver le Dockerfile de mon image sur GitHub : https://github.com/teddy-ferdinand/docker-ghost-themes

Comme vous pouvez le voir, l'image est très basique, elle se base sur une image ubuntu (qui à l'avantage d'être assez légère) sur laquelle j'ai installé curl et zip.

Il y a ensuite un script shell que je copie dessus.

Ce script permet :

  • De s'authentifier en utilisant un token API (décrit plus bas)
  • De pousser le nouveau thème en lui donnant un nom unique
  • D'activer le thème après qu'il ait été poussé

Cette image est ensuite construite automatiquement par DockerHub

Vous pouvez d'ailleurs trouver l'image construite à ce lien : https://hub.docker.com/r/tferdinand/docker-ghost-themes

Préparation d'une clé API sur Ghost

Du côté de Ghost, il est nécessaire de préparer une clé API d'administration pour pouvoir accéder aux APIs de thèmes.

Il suffit pour ça d'aller dans l'interface de back office et sélectionner ensuite "Integrations"

Ensuite, cliquez sur "Add custom integration", puis donner un nom à celle ci.

La clé qui nous intéresse est celle nommé "Admin API Key" (en rouge ci dessous).

Préparer un repository Github avec votre thème

Enfin, il va nous falloir un repository GitHub pour que CircleCI puisse faire son déploiement.

Nous allons donc créer un repository GitHub, qui peut être privé, comme pour moi. En effet, le thème que j'utilise est soumis à licence et je ne peux pas le partager publiquement.

Dans ce repository, nous allons en plus ajouter un fichier .circle/config.yml. C'est ce fichier qui servira de base pour les déploiements, dans lequel nous indiquerons les images de bases et les actions à effectuer.

J'ai préparé un repository public contenant le thème de base de Ghost, Casper, et le workflow Circle, vous pouvez ce repository ici : https://github.com/teddy-ferdinand/ghost-deployment-demo

Dans le fichier de configuration circleci, on trouve :

  • Lignes 4 à 6 : La configuration de base pour CircleCI, avec le nom de l'image utilisée et le dimensionnement au niveau Docker (small = 1vCPU / 2Go de mémoire)
  • Lignes 7 à 25, la description de mes étapes, avec la partie test et prod, vous pouvez constater qu'il y a donc deux grandes étapes, la préparation de l'archive, et son envoi avec le script décrit plus tôt
  • A partir de la ligne 27 : La description de mon workflow de déploiement, qui est très basique dans mon cas.

Import du projet dans CircleCI

Maintenant que nous avons tout préparé, rendez vous sur CircleCI et connectez vous à votre compte. Si vous n'avez pas de compte CircleCI, vous pouvez vous connecter directement avec votre compte GitHub.

Une fois connecté, cliquez sur "Add project" dans le menu de gauche.

Cliquez ensuite sur "Set Up Project" sur la ligne correspondant à votre projet.

Vous pouvez ensuite directement cliquer sur "Start Building" en haut à droite, vu que nous avons déjà notre fichier de configuration CircleCI. Sélectionnez ensuite "Add manually" pour les même raisons puis "Start Building" de nouveau.

Votre projet est maintenant prêt, et un build se lance... mais il échoue!

Pas de panique, c'est normal, notre projet étant prêt avant, CircleCI cherche un contenu sur master et non testing (la branche sur laquelle j'ai poussé).

Avant de relancer notre build, nous allons juste créer deux variables, en cliquant sur "Project settings" puis "Environment Variables".

Les deux variables que nous allons créé sont :

  • testing_api_url : qui pointent vers votre url du serveur Ghost de test
  • testing_api_key : qui contient la clé que nous avons créé plus tôt

Pourquoi mettre ces valeurs, et surtout un secret ici ?

Déjà, cela nous évite de les avoir sur GitHub, ensuite, les valeurs des variables créée dans CircleCI sont automatiquement masquées, mais le workflow peut y accéder sans soucis. Comme vous avez du le voir sur le workflow utilisé sur GitHub, j'utilise en fait ces variables pour pointer vers les bons environnements.

Il suffit maintenant de faire un commit sur la branche "testing" pour lancer notre build de test, qui se déroule cette fois sans soucis.

En allant sur l'interface de Ghost, vous avez normalement un nouveau thème déployé et activé avec un identifiant unique.

Il me suffit maintenant de créer deux nouvelles variables d'environnement prod_api_url et prod_api_key, de la même manière que les précédente pour rendre fonctionnel mon déploiement sur la production. Un merge sur le master permettra d'effectuer le déploiement.

Pour terminer

Comme vous avez pu le voir, il est assez simple de déployer un theme automatiquement sur Ghost.

Néanmoins, j'ai rencontré quelques soucis lors de la mise en place :

  • Le code pour gérer le token JWT sur le site de ghost n'est pas fonctionnel en shell.
  • L'API de gestion des thème n'est pas documentée, j'ai du observer le comportement du back-office pour mettre en place mon script.

Enfin, comme d'habitude, le but n'est pas forcément de vous donner directement les outils en disant "go, ca fonctionne", mais plutot de vous donner les clés pour comprendre et implémenter comme vous le préférez. Les scripts que j'ai mis à dispositions ont été fait rapidement en mode "proof of concept" mais ne sont pas utilisable en production tel quels (notamment à cause du manque de contrôle des codes retours), j'essaierai de les mettre à jour prochainement.