Introduction
Dans ce billet, j’explique comment nous avons utilisé GitLab et OpenShift pour déployer automatiquement S-Filer dès qu’un changement est apporté à notre dépôt. C’est un outil très utile, pour quelques raisons. D’abord, lorsqu’une nouvelle fonction est poussée dans le dépôt, nous pouvons la voir et l’utiliser sans avoir à extraire le code et à démarrer l’environnement nous-mêmes, ce qui prend du temps. Autre avantage: on peut déployer plusieurs applications sur le même hôte sans se soucier de conflits de ports ni de rien de ce genre. Par exemple, on peut avoir plusieurs bases de données MySQL à l’écoute sur le même port, sans problème. Enfin, tout cela est automatique! Après l’effort initial, il y a peu ou pas d’entretien à faire et vous disposez d’un excellent nouvel outil.
Terminologie
Avant d’aborder l’intégration sur le plan technique, voyons quelques définitions. D’abord, qu’est-ce qu’OpenShift? Selon Wikipédia: « OpenShift est un produit logiciel de Red Hat pour le déploiement et la gestion de logiciels en conteneurs. Il s’agit d’une distribution prise en charge de Kubernetes utilisant des conteneurs Docker et des outils DevOps pour accélérer le développement d’applications. » (https://en.wikipedia.org/wiki/OpenShift) Essentiellement, OpenShift est une surcouche de Kubernetes dotée de fonctions supplémentaires. Si vous ne savez pas ce qu’est Kubernetes, voici un extrait de la documentation officielle: « Kubernetes fournit un environnement de gestion centré sur les conteneurs. Il orchestre l’infrastructure de calcul, de réseau et de stockage pour le compte des charges de travail des utilisateurs. Cela offre une bonne part de la simplicité d’une plateforme-service (PaaS) avec la souplesse d’une infrastructure-service (IaaS), et permet la portabilité entre les fournisseurs d’infrastructure. » (https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/) OpenShift nous permet de déployer facilement différentes versions d’une application, puisqu’elles seront complètement isolées les unes des autres, comme si elles se trouvaient sur des machines physiques distinctes.
Mise en œuvre
Maintenant que nous avons clarifié ce qu’est OpenShift, voyons comment nous l’avons intégré à GitLab. Voici d’abord le schéma décrivant notre pipeline GitLab:

La première étape de la tâche « Deploy Application » (en vert) consiste à créer le projet OpenShift. Simplement dit, un projet est une façon de cloisonner chaque application. Ici, j’utilise comme nom de projet le nom de la branche git dans laquelle le changement a été fait. Vous pouvez utiliser la variable $CI_COMMIT_REF_SLUG dans votre fichier gitlab-ci.yml: c’est le nom de la branche formaté pour être utilisable dans une URL.
La deuxième étape consiste à créer le gabarit à l’intérieur du projet. Après le déploiement du gabarit, OpenShift se met à créer chacune des composantes qui y sont définies. Dans notre cas, nous avons 2 bases de données MySQL, 1 serveur S-Filer et 1 passerelle S-Filer, qui sont des applications Java. L’image MySQL étant disponible d’emblée, OpenShift la télécharge et démarre les deux bases de données. Il tente ensuite de télécharger les images du serveur et de la passerelle S-Filer, mais elles ne sont pas encore disponibles: OpenShift attendra donc qu’elles le soient. Dans le gabarit, vous pouvez aussi configurer vos routes, qui donnent accès à votre application depuis l’extérieur de la grappe. Nous en avons deux:
https://gui.$CI_COMMIT_REF_SLUG.openshift.example.com→ port 8081 du conteneur du serveur S-Filerhttps://config.$CI_COMMIT_REF_SLUG.openshift.example.com→ port 8090 du conteneur du serveur S-Filer
C’est ce qui permet de « réutiliser » le même port. En arrière-plan, OpenShift acheminera votre requête vers le bon conteneur, puisqu’il sait quel nom d’hôte appartient à quelle application et que chaque route est liée à un port précis. Il importe donc d’avoir des noms d’hôtes uniques, car une même route ne peut pas être acheminée vers différents ports. Un gabarit contient une grande quantité d’informations et il serait impossible de tout couvrir ici; pour en savoir plus, je vous invite à consulter la documentation officielle d’OpenShift.
Les deux dernières étapes consistent à construire les images et à les pousser vers le registre OpenShift. Une fois les images poussées, OpenShift les déploie automatiquement, après quoi votre application devrait être accessible par les routes configurées plus haut. Construire une image est plutôt simple: il vous faut un Dockerfile contenant des commandes qui seront exécutées sur l’image de base de votre choix. Par exemple, le Dockerfile de la passerelle S-Filer se fonde sur openjdk:8-jre, lui-même fondé sur Debian. Dans le Dockerfile, nous définissons aussi des commandes; voici en gros les étapes que nous suivons:
- Copier les répertoires pertinents dans l’image.
- Créer des dossiers pour les données persistantes.
- Modifier un fichier de configuration.
- Préciser le volume et les ports exposés.
Ensuite, vous pouvez éventuellement ajouter un point d’entrée, soit un script exécuté au démarrage de l’image.
Voici le contenu de notre fichier gitlab-ci.yml décrivant la définition de tâche qui met en œuvre le déploiement:
deploy-sfiler:
stage: deploy
script:
# OpenShift and Docker login
- "oc login https://openshift.example.com:443 -u=registry_user -p=$REGISTRY_USER_PASSWORD"
- "docker login -u registry_user -p $(oc whoami -t) docker-registry-default.apps.openshift.example.com"
# Delete OpenShift project. ( "|| true;" makes sure that the job continues even if the delete does not exit successfully.)
- "{ oc delete project $CI_COMMIT_REF_SLUG || true; }"
# Build project
- "mvn -DskipTests -DexcludedGroups=database -DtrimStackTrace=false install"
# Deploy to OpenShift
- "oc new-project $CI_COMMIT_REF_SLUG"
- "oc process -p BRANCH_NAME=$CI_COMMIT_REF_SLUG -p CONFIG_MYSQL_USER=user -p CONFIG_MYSQL_PASSWORD=Passw0rd -p MYSQL_USER=user -p MYSQL_PASSWORD=Passw0rd -p SFILER_ADMIN_EMAIL=admin@dev.okiok.com -f sfiler-server/sfiler-ephemeral-template.json | oc create -f - "
# Build sfiler-gateway image and push it
- "docker build -f sfiler-gateway/Dockerfile -t docker-registry-default.apps.openshift.example.com/$CI_COMMIT_REF_SLUG/sfiler-gateway:latest sfiler-gateway/"
- "docker push docker-registry-default.apps.openshift.example.com/$CI_COMMIT_REF_SLUG/sfiler-gateway"
# Build sfiler-server image and push it
- "docker build -f sfiler-server/Dockerfile -t docker-registry-default.apps.openshift.example.com/$CI_COMMIT_REF_SLUG/sfiler-server:latest sfiler-server/"
- "docker push docker-registry-default.apps.openshift.example.com/$CI_COMMIT_REF_SLUG/sfiler-server"
environment:
name: $CI_COMMIT_REF_SLUG
url: https://gui.$CI_COMMIT_REF_SLUG.openshift.example.com/sfiler
on_stop: stop_review_app
tags:
- "docker-builder"
Enfin, vous pouvez définir une tâche pour arrêter manuellement le déploiement. C’est nécessaire pour nettoyer vos environnements et ne pas consommer de ressources inutilement.
# This is a manual step that stops the deployment and deletes the OpenShift project.
stop_review_app:
stage: deploy
when: manual
environment:
name: $CI_COMMIT_REF_SLUG
action: stop
script:
# OpenShift login
- "oc login https://openshift.example.com:443 -u=registry_user -p=$REGISTRY_USER_PASSWORD"
# Delete OpenShift project. ( "|| true;" makes sure that the job continues even if the delete does not exit successfully.)
- "{ oc delete project $CI_COMMIT_REF_SLUG || true; }"
tags:
- "docker-builder"
Une fois le pipeline terminé, vous trouverez un lien vers votre environnement dans votre demande de fusion sur GitLab. C’est le résultat de l’ajout d’un bloc environment dans la définition de la tâche.

Conclusion
Et voilà! Votre application se déploie maintenant automatiquement dès qu’un changement est ajouté à votre dépôt, et ce nouvel outil se révélera très utile pour réviser des changements difficiles à évaluer en texte seulement: images, bogues d’affichage, etc.
