Gitlab CI/CD - intégration continue et déploiement continu
Introduction
Cette quête est conçue pour explorer le concept de CI/CD, se concentrant sur la plateforme GitLab CI/CD et comment il peut être utilisé pour automatiser le déploiement d'une application Node.js.
En progressant, tu apprendras les bases du CI/CD, son importance, et comment GitLab facilite ce processus avec ses pipelines.

📚 Pré-requis
Avant de commencer, il est nécessaire d'avoir :
- Un compte sur gitlab.com
- Des connaissances de base de Git
- Avoir installé nodejs / npm et pm2.
- Un serveur distant pour le déploiement de l'application avec nodejs / npm et pm2
🤓 Objectifs
✅ Comprendre le CI/CD et son importance ✅ Faire connaissance avec Gitlab CI/CD ✅ Configurer un pipeline GitLab CI/CD pour un projet Node.js ✅ Automatiser le déploiement sur un serveur distant
Sommaire
📖 Qu'est-ce que le CI/CD ?
Le CI/CD, pour Continuous Integration/Continuous Deployment, est un ensemble de pratiques destinées à automatiser le processus de livraison des applications.
La partie CI se concentre sur l'intégration automatique et le test du code à chaque modification, tandis que le CD s'occupe du déploiement automatique des versions testées vers l'environnement de production ou d'autres environnements de test.
📖 Focus sur le CI
L'intégration continue (CI) est une pratique de développement logiciel où les membres d'une équipe intègrent leur travail fréquemment, généralement chaque personne au moins une fois par jour.
Cette approche permet de détecter et de résoudre les erreurs rapidement, améliorant ainsi la qualité du logiciel et réduisant le temps nécessaire pour livrer des modifications.
Wikipédia - Intégration continue
Principe de base
Le principe de base de la CI est simple : à chaque fois qu'un développeur pousse des modifications vers le dépôt de code source (Gitlab, Github, Bitbucket, ...), un serveur de CI automatise la construction du projet et exécute une série de tests pour s'assurer que les modifications n'introduisent pas d'erreurs.
Avantages de la CI
- Détection rapide des erreurs : En intégrant et en testant le code régulièrement, les erreurs sont détectées tôt, ce qui simplifie leur résolution.
- Amélioration de la qualité du logiciel : Les tests réguliers garantissent que le logiciel répond toujours aux exigences de qualité.
- Réduction du temps de mise sur le marché : En automatisant le processus de test, le temps nécessaire pour développer et déployer de nouvelles fonctionnalités ou corrections est réduit.
- Feedback immédiat : Les développeurs reçoivent un retour immédiat sur l'état de leur code, leur permettant de faire des corrections rapidement.
Mise en œuvre de la CI avec GitLab CI/CD
GitLab CI/CD utilise un fichier .gitlab-ci.yml pour définir les étapes du pipeline CI.
Ce fichier spécifie les tâches à exécuter, les scripts à lancer, et les conditions sous lesquelles ces tâches doivent être exécutées. Voici un exemple simple pour un projet Node.js :
stages:
- test
test_app:
stage: test
script:
- npm install
- npm run test
📖 Focus sur le CD
Le déploiement continu (CD) est une extension de l'Intégration Continue (CI), où chaque modification de code qui passe avec succès à travers la phase de test est automatiquement déployée dans l'environnement de production ou de staging.
Cela permet une livraison rapide et fiable des fonctionnalités aux utilisateurs finaux, avec peu ou pas d'intervention manuelle.
Wikipédia - Déploiement continue
Principe de base
Le CD vise à automatiser entièrement le processus de déploiement.
Après qu'une modification de code a réussi tous les tests automatisés, cette modification est automatiquement déployée dans l'environnement cible.
Cette approche réduit le risque d'erreurs humaines et accélère le processus de mise en production.
Avantages du CD
- Rapidité : Les modifications de code atteignent plus rapidement les utilisateurs finaux, permettant une réactivité accrue aux besoins du marché.
- Fiabilité : Le déploiement automatisé, combiné avec des tests approfondis, augmente la fiabilité des mises en production.
- Simplification : Le processus de déploiement est simplifié, réduisant le besoin de gestion manuelle et les erreurs qui en découlent.
📖 GitLab CI/CD
GitLab CI/CD est une partie intégrante de GitLab permettant d'automatiser le processus de CI/CD à travers des pipelines définis dans un fichier .gitlab-ci.yml.
Chaque modification du dépôt déclenche l'exécution du pipeline, qui peut inclure des étapes telles que la construction, le test, et le déploiement de l'application.
Fonctionnement de GitLab CI/CD
Lorsqu'un développeur pousse des modifications dans un dépôt GitLab, le pipeline CI/CD est automatiquement déclenchée en fonction des règles définies dans le fichier .gitlab-ci.yml.
Voici les étapes typiques d'un pipeline :
- Build : Construction du code source en binaires ou en autres formats utilisables.
- Test : Exécution de tests automatisés pour vérifier la qualité et la sécurité du code.
- Deploy : Déploiement du code dans un environnement de staging ou de production.
Les pipelines peuvent être configurés pour s'exécuter de manière conditionnelle, sur des branches spécifiques, ou en réponse à des événements particuliers, offrant une flexibilité totale dans la gestion du cycle de vie du développement logiciel.
Gitlab - Usecases and examples
Avantages de GitLab CI/CD
- Intégration et configuration simples : Étant une solution tout-en-un, GitLab facilite l'intégration de la CI/CD dans le workflow de développement.
- Automatisation complète : De la construction à la livraison, tout le processus est automatisé, réduisant les erreurs humaines et accélérant le temps de mise sur le marché.
- Flexibilité : Les pipelines peuvent être aussi simples ou complexes que nécessaire, supportant des workflows de déploiement sophistiqués.
- Visibilité et contrôle : GitLab fournit une interface utilisateur intuitive pour visualiser les pipelines, les exécutions de jobs, et les résultats des tests, permettant un suivi et un contrôle faciles.
:shell: Mise en situation
Nous allons configurer un pipeline GitLab CI/CD simple pour un projet Node.js simple, qui sera automatiquement déployé sur un serveur distant à chaque push sur la branche main.
Étape 1 : Préparer le projet Node.js
Créer un projet simple à l'aide du framework Express :
npm init -y
npm install express
Ajouter un fichier app.js à la racine du projet avec le contenu suivant pour démarrer un serveur web basique :
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello World!'));
if (require.main === module) {
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`App listening on port ${port}!`));
}
module.exports = app;
Tester l'application localement en exécutant node app.js et essayer d'afficher le contenu depuis un navigateur en saisissant l'adresse http://localhost:3000.
Si tu obtiens une erreur du genre listen EADDRINUSE: address already in use :::3000, c'est que le port 3000 est déjà utilisé par une autre application.
Penses à modifier cela si ça coince.
Étape 2 : Ajouter des tests au projet
Créer une bibliothèque de tests comme jest et supertest pour ajouter des tests automatisés au projet :
npm install --save-dev jest supertest
Créer un répertoire pour les scripts de test. Il doit être à la racine du projet et on va le nommer tests/.
Créer un fichier dans ce répertoire, nommé app.test.js. On va y mettre ce qui suit :
const request = require('supertest');
const app = require('../app.js');
describe('GET /', () => {
it('responds with Hello World!', done => {
request(app)
.get('/')
.expect('Hello World!', done);
});
});
Modifier le fichier package.json pour ajouter l'exécution des tests avec Jest et les étapes de démarrage et de build :
{
... // ne pas modifier ce qui se trouve avant
"scripts": {
"start": "node app.js",
"test": "jest",
"build": "npm install"
},
... // ne pas modifier ce qui se trouve après
}
Étape 3 : Créer un dépôt GitLab et pousser le projet
Créer un nouveau dépôt sur gitlab.com pour le projet Node.js
Initialiser le dépôt git en local si ce n'est pas déjà fait, puis pousser le projet sur Gitlab
git init -b main
git add .
git commit -m "Initial commit"
git remote add origin <URL_DE_DEPOT_GITLAB>
git push -u origin main
Remplaces <URL_DE_DEPOT_GITLAB> par l'url de ton dépôt, en pensant à retirer les <>.
Étape 4 : Configurer le pipeline GitLab CI/CD
Ajouter un fichier .gitlab-ci.yml à la racine du projet avec le contenu suivant
stages:
- test
- build
- deploy
test_app:
stage: test
image: node:latest
script:
- npm install
- npm run test
build_app:
stage: build
image: node:latest
script:
- npm install
artifacts:
paths:
- ./
exclude:
- node_modules/
deploy_app:
stage: deploy
image: alpine:latest
before_script:
- apk update && apk add openssh-client rsync
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh && touch ~/.ssh/known_hosts
- chmod 700 ~/.ssh
- ssh-keyscan -p <DEPLOY_SERVER_PORT> -t ed25519 <DEPLOY_SERVER_IP> >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
- echo "StrictHostKeyChecking=no" > ~/.ssh/config
script:
- rsync -avz ./ <DEPLOY_USER>@<DEPLOY_SERVER_IP>:<DEPLOY_DIR> -e "ssh -p <DEPLOY_SERVER_PORT>"
- echo "Deploying application..."
- >
ssh <DEPLOY_USER>@<DEPLOY_SERVER_IP> -p <DEPLOY_SERVER_PORT>
"
. ~/.nvm/nvm.sh &&
cd <DEPLOY_DIR> &&
npm install --production &&
(pm2 start app.js --name "mon-application" --update-env || pm2 restart "mon-application" --update-env) &&
exit
"
only:
- main
Remplaces <DEPLOY_USER>, <DEPLOY_SERVER_IP>, <DEPLOY_SERVER_PORT> et <DEPLOY_DIR> par tes informations de connexion SSH et le chemin vers ton application côté serveur distant.
Et bien penser à retirer les <>, sinon ça ne fonctionnera pas.
Pour l'authentification, c'est la clé privée préchargée dans le bloc before_script, qui sera utilisée.
Si tu veux faire quelque chose de propre, il te faut créer des variables dans Gitlab pour chaque valeur.
Concernant le job test_app, il est important de noter qu'ici on utilise l'image Docker node:latest. Il est idéal d'utiliser une version alignée avec celle que tu utilises en local, pour éviter les potentielles d'erreur dûes aux différences entre les versions de npm/nodejs.
Voici quelques explications sur le contenu de ce fichier :
stages
Définit les étapes du pipeline dans l'ordre d'exécution. Chaque stage peut contenir plusieurs jobs, mais ici, chaque étape contient un seul job.
test_app
- stage: test : Ce job appartient à l'étape
test. Il s'exécute en premier. - image: node:latest : Utilise la dernière image Docker officielle de Node.js pour exécuter le job.
- script : Les commandes à exécuter. Ici, il installe les dépendances du projet (
npm install) et lance les tests (npm run test).
build_app
- stage: build : Ce job appartient à l'étape
build. Il s'exécute aprèstest. - script : Similaire au job
test_app, il installe les dépendances. Cependant, dans un contexte réel, cette étape pourrait être utilisée pour compiler le code ou préparer des artefacts. - artifacts : Spécifie les fichiers ou dossiers à conserver après l'exécution du job. Ici, tout le répertoire courant est conservé, à l'exception du dossier
node_modules.
deploy_app
- stage: deploy : Dernière étape, elle déploie l'application sur un serveur de production.
- image: alpine:latest : Utilise la dernière image Docker d'Alpine Linux, une distribution légère, pour le job.
- before_script : Prépare l'environnement pour le déploiement, notamment en installant
openssh-clientetrsync, en configurantssh-agent, et en ajustant les paramètres SSH. - script :
- Utilise
rsyncpour transférer les fichiers du projet vers le serveur de production. - Se connecte au serveur via SSH et exécute une série de commandes pour naviguer dans le répertoire de déploiement, installer les dépendances de production avec
npm, et démarrer ou redémarrer l'application avecpm2.
- Utilise
- only : Définit que ce pipeline ne s'exécute que sur la branche
main.
Configurer l'accès SSH entre GitLab et ton serveur distant pour permettre le déploiement :
- générer une clé ssh au format ed25519
- copier le contenu de la clé privée pour l'ajouter dans Gitlab en tant que variable
- nommer la variable
SSH_PRIVATE_KEYet y insérer le contenu de la clé privée - copier le contenu de la clé publique et l'ajouter sur le serveur distant dans
~/.ssh/authorized_keys
Pousser le fichier .gitlab-ci.yml sur le dépôt Gitlab
git add .gitlab-ci.yml
git commit -m "Add GitLab CI/CD configuration"
git push
Étape 5 : Vérifier le pipeline
Après avoir poussé le fichier de configuration CI/CD, se rendre sur GitLab et ouvrir le projet pour voir le pipeline en action sous l'onglet "Build > Pipelines". Tu devrais voir un pipeline en statut "Running".
Si tu cliques, tu auras le détail du ou des job-s en cours.
Et en cliquant sur un job, tu peux voir les logs pour analyser ce qu'il se passe en quasi temps réel.
Si tout est configuré correctement, tu devrais voir un job nommé deploy_job qui, une fois terminé, aura poussé le code de ton projet sur ton serveur distant.

☝️ Résumé
L'intégration continue est une pratique de développement où les développeurs fusionnent leurs modifications de code dans un dépôt centralisé fréquemment, permettant des tests automatisés et des builds réguliers pour détecter rapidement les erreurs.
Le déploiement continu étend la CI en automatisant le déploiement de toutes les modifications de code approuvées dans l'environnement de production, permettant une livraison rapide et continue des fonctionnalités aux utilisateurs.
GitLab CI/CD est une plateforme intégrée qui facilite la CI/CD en automatisant le processus de test et de déploiement à travers un fichier de configuration .gitlab-ci.yml, offrant un pipeline de déploiement fluide et une visibilité complète sur le cycle de vie du développement logiciel.
📝 Quiz
true||true|||true
# Qu'est-ce que le CI dans CI/CD ?
[x] Integration Continue
[] Déploiement Continu
[] Livraison continue
# GitLab CI/CD utilise quel fichier pour configurer les pipelines ?
[x] .gitlab-ci.yml
[] gitlab-config.json
[] .ci-config.yml
# Pourquoi est-il important d'automatiser le déploiement ?
[] Pour permettre la mise en prod le vendredi
[x] Pour réduire les erreurs humaines et améliorer l'efficacité
[] Pour simplifier le travail des développeurs
💪 Challenge
Ton défi est de créer un pipeline de déploiement pour un projet PHP simple, contenant un script index.php qui affiche "Hello world!".
Le tout doit être hébergé sur GitLab.
Le pipeline doit inclure les étapes de construction, de test et de déploiement automatique sur un serveur distant.
🧐 Critères d'acceptation
La réponse doit être fournie sous forme d'un dépôt gitlab dans lequel on retrouve :
- le fichier
.gitlab-ci.yml - le code source du projet PHP
- au moins un script de test
- un readme.md dans lequel figure le descriptif des étapes et des outils utilisés pour la configuration du serveur distant