Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

⚙️ Jenkins – CI/CD, Pipelines & Déploiement

Guide complet IDEO‑Lab sur le serveur d'intégration continue (Pipeline, Groovy, Jenkinsfile).

1.1 Facile

Vue d'ensemble

CI/CD, Serveur d'automatisation, Jobs.

CI/CD Automatisation
1.2 Facile

Architecture

Controller (Master) / Agent (Slave).

Controller Agent
1.3 Facile

Prérequis : Java (JDK)

Installation OpenJDK (11 ou 17 Requis).

Java JDK 11/17
1.4 Moyen

Installation Linux

apt (Debian/Ubuntu) & dnf (RHEL/Rocky).

apt dnf
1.5 Facile

Installation Docker

docker run (persistance), docker-compose.

Docker Compose
1.6 Facile

Setup Wizard

Déverrouillage, initialAdminPassword, plugins.

Wizard Plugins
2.1 Facile

Gérer Jenkins & Plugins

Gérer les plugins (install, update).

Manage Jenkins Plugins
2.2 Facile

Job 1: Freestyle Project

Le job "classique" (via l'UI), SCM, Build steps.

Freestyle UI
3.1 Moyen

Pipeline as Code

Jenkinsfile, "Pipeline as Code", SCM.

Jenkinsfile Pipeline
3.2 Moyen

Declarative vs Scripted

Comparaison des deux syntaxes Pipeline.

Declarative Scripted
3.3 Avancé

Declarative: Syntaxe

pipeline, agent, stages, steps, post, environment.

pipeline {} stages {}
3.4 Moyen

Declarative: Steps (étapes)

sh, bat, dir, git, junit, archiveArtifacts.

sh archiveArtifacts
3.5 Avancé

Scripted Pipeline (Groovy)

node {}, stage {}, syntaxe Groovy, try/catch.

Groovy node {}
4.1 Avancé

Shared Libraries

Factoriser le code (vars/), @Library.

Shared Library DRY
4.2 Moyen

Multibranch Pipeline

Scan auto des branches (Jenkinsfile).

Multibranch Git
4.3 Moyen

Artifacts & Credentials

archiveArtifacts, stash, withCredentials.

Credentials Artifacts
4.4 Moyen

Triggers (Déclencheurs)

cron, pollSCM, Webhooks (GitHub).

Webhooks cron
5.1 Facile

Blue Ocean (UI)

Interface moderne pour visualiser les Pipelines.

Blue Ocean UI
5.2 Moyen

Sécurité (Matrix)

Gestion des utilisateurs, Matrix Security.

Security Matrix
6.1 Moyen

Cheat-sheet Jenkinsfile

Syntaxe Declarative (pipeline, stages, steps...).

cheat Jenkinsfile
1.1 Vue d'ensemble : Le Serveur d'Automatisation
Qu'est-ce que Jenkins ?

Jenkins est un serveur d'automatisation open-source (écrit en Java). C'est l'outil de **CI/CD** (Intégration Continue / Déploiement Continu) le plus utilisé au monde.

Son rôle est d'automatiser les phases non-humaines du développement logiciel (build, test, déploiement).

CI/CD (Intégration Continue / Déploiement Continu)

CI (Continuous Integration) :

  1. Un développeur "push" son code vers Git.
  2. Jenkins détecte le push (via Webhook).
  3. Jenkins "build" le projet (ex: npm install, mvn package).
  4. Jenkins lance les tests unitaires (npm test).
  5. Jenkins rapporte le résultat (OK/Échec) au développeur.

CD (Continuous Deployment) :

  1. Si la CI est OK, Jenkins "package" l'application (ex: image Docker).
  2. Jenkins déploie l'application sur un serveur (Staging, Prod).

Jenkins vs (GitLab CI, GitHub Actions)
CritèreJenkinsGitLab CI / GitHub Actions
HébergementAuto-hébergé (On-premise / VPS).SaaS (Cloud) ou Auto-hébergé (Runners).
FlexibilitéExtrême. Des milliers de plugins.Plus simple, mais lié à l'écosystème Git.
ConfigurationJenkinsfile (Groovy) ou UI..gitlab-ci.yml / .github/workflows/ (YAML).
Courbe d'apprentissageÉlevée (Java, Plugins, Agents).Moyenne (YAML).
1.2 Architecture : Controller / Agent
Controller (ex-Master)

Le Controller (Contrôleur) est le serveur central (le "cerveau").
Il ne fait pas de travail de build.

  • Stocke la configuration (jobs, plugins).
  • Gère l'interface web (Port 8080).
  • Planifie et distribue les "builds" aux Agents.
Agent (ex-Slave)

Un Agent (Agent) est un "worker" (l'esclave) qui exécute les tâches.

  • Peut être une VM, un conteneur Docker, un pod K8s.
  • Possède les "outils" (ex: Java, Node.js, Docker).
  • Reçoit les ordres du Controller ("Build ce projet") et exécute les étapes.
Schéma de flux
[Image d'une architecture Jenkins Controller/Agent]
(Dev -> 'git push')
   |
   ▼ (Webhook)
+-----------------------+
| Controller (Serveur)  |
| (Port 8080)           |
| (Gère l'UI, Planifie) |
+-----------------------+
   |
   | (Lance le build via SSH ou JNLP)
   |
   +----------+-----------------+
   |          |                 |
   ▼          ▼                 ▼
+--------+ +--------+       +--------+
| Agent 1| | Agent 2|       | Agent 3|
| (Linux)| | (Win)  |       | (Docker)|
| (Java 11)| (NodeJS) |       | (Python)|
+--------+ +--------+       +--------+
 (Exécute le build, 'npm install'...)
1.3 Prérequis : Java (JDK)
Jenkins est Java

Jenkins est une application .war (Web Archive) Java. Il nécessite un Java Development Kit (JDK) (ou JRE) pour s'exécuter (sur le Controller et les Agents).

Version Requise
  • Jenkins LTS (actuel) : Java 11 ou Java 17. (Java 8 est obsolète).
Installation (OpenJDK 17 - Ubuntu/Debian)
sudo apt update
sudo apt install -y openjdk-17-jdk

# Vérifier
java -version
# openjdk version "17.0.x" ...
Installation (OpenJDK 17 - RHEL/Rocky)
sudo dnf install -y java-17-openjdk-devel

# Vérifier
java -version
1.4 Installation Linux (apt/dnf)
Ubuntu / Debian (Dépôt officiel Jenkins)
# (Assurez-vous que JDK 17 est installé)

# 1. Ajouter la clé GPG
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \
  /usr/share/keyrings/jenkins-keyring.asc > /dev/null

# 2. Ajouter le dépôt
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
  https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null
  
# 3. Installer
sudo apt-get update
sudo apt-get install -y jenkins
RHEL / Rocky / AlmaLinux (Dépôt officiel)
# 1. Ajouter le dépôt
sudo wget -O /etc/yum.repos.d/jenkins.repo \
    https://pkg.jenkins.io/redhat-stable/jenkins.repo

# 2. Importer la clé GPG
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key

# 3. Installer
sudo dnf install -y jenkins
Post-Installation (systemd)
# Démarrer et activer
sudo systemctl enable --now jenkins

# Vérifier le statut
sudo systemctl status jenkins

# (Données Jenkins)
# /var/lib/jenkins (JENKINS_HOME)

# (Configuration)
# /etc/default/jenkins (Debian)
# /etc/sysconfig/jenkins (RHEL)

Une fois démarré, Jenkins est accessible sur http://[IP_SERVEUR]:8080.
(Ouvrir le port 8080 dans le firewall !)

1.5 Installation Docker (Recommandé en Dev)
docker run (Simple)

L'image officielle (jenkins/jenkins:lts) est recommandée. La persistance de /var/jenkins_home est cruciale.

docker run -d \
    --name jenkins \
    -p 8080:8080 \
    -p 50000:50000 \
    -v jenkins_home:/var/jenkins_home \
    jenkins/jenkins:lts-jdk17

# -p 8080: (UI Web)
# -p 50000: (Agents JNLP)
# -v jenkins_home:... (Volume pour les données)
docker-compose.yml (Plus robuste)
version: '3.8'
services:
  jenkins:
    image: jenkins/jenkins:lts-jdk17
    container_name: jenkins
    ports:
      - "8080:8080"
      - "50000:50000"
    volumes:
      - jenkins_home_data:/var/jenkins_home
    restart: unless-stopped

volumes:
  jenkins_home_data:
1.6 Setup Wizard (Post-Installation)
1. Déverrouillage

Lors du premier accès (http://localhost:8080), Jenkins demande un mot de passe initial (pour prouver que vous êtes l'admin).

Ce mot de passe se trouve sur le serveur :

# (Si install Linux)
sudo cat /var/lib/jenkins/secrets/initialAdminPassword

# (Si install Docker)
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
2. Plugins & Admin

Customize Jenkins :
-> "Install suggested plugins" (Recommandé pour les débutants).

Create First Admin User :
Créez votre propre compte (ex: ideo_admin) pour ne plus utiliser le mot de passe généré.

2.1 Gérer Jenkins & Plugins
"Manage Jenkins" (Administrer Jenkins)

C'est le panneau de configuration central de Jenkins. C'est ici que vous gérez :

  • System : Configuration globale (URL, variables d'env...).
  • Tools : (Important) Définir les outils (JDK, Git, Node.js) pour les Agents.
  • Nodes and Clouds : Ajouter/Gérer les Agents.
  • Credentials : (Important) Stocker les secrets (mots de passe, clés SSH).
  • Plugins : Gérer les plugins.
  • Security : Gérer les utilisateurs et les permissions.
Gestion des Plugins

La puissance de Jenkins vient de ses plugins. (Manage Jenkins -> Plugins).

Plugins "indispensables" à installer (s'ils ne le sont pas) :

PluginUsage
Blue Ocean(Voir 5.1) Interface UI moderne pour les Pipelines.
Pipeline(Core) Le moteur Jenkinsfile.
GitIntégration Git.
Docker PipelinePermet d'utiliser docker.build(), docker.run() dans un Jenkinsfile.
SSH AgentFournit des clés SSH aux builds (pour git pull ou ssh deploy).
2.2 Job 1: Freestyle Project (Le "Classique")
L'ancien mode (via l'UI)

Un "Freestyle Project" est le job historique de Jenkins. Toute la configuration se fait via l'interface graphique (clics, formulaires).

Avantage : Très simple pour les débutants et les tâches basiques.
Inconvénient : La configuration n'est pas versionnée (pas dans Git). Difficile à reproduire.

Création
  1. Dashboard -> New Item.
  2. Entrer un nom (ex: "Mon_Job_Freestyle").
  3. Choisir Freestyle project.
Configuration (SCM)

Dans la page de configuration du job :

Source Code Management (SCM) :

  • Cocher Git.
  • Repository URL : https://github.com/mon-user/mon-projet.git
  • Credentials : (Ajouter un "Username with password" ou "SSH Username")
  • Branch Specifier : */main
Configuration (Build & Post)

Build Steps :

  • Add build step -> Execute shell.
  • Command :
    echo "Début du build..."
    npm install
    npm test

Post-build Actions :

  • Add post-build action -> Archive the artifacts.
  • Files to archive : build/**, *.log

Cliquez sur Save, puis Build Now.

3.1 "Pipeline as Code" (Jenkinsfile)
Le "Nouveau" mode (Moderne)

"Pipeline as Code" est la méthode moderne. La configuration n'est plus dans l'UI de Jenkins, mais dans un fichier texte appelé Jenkinsfile, stocké à la racine de votre projet Git.

Avantages
  • Versionné : La CI/CD est dans Git, comme le code (traçabilité).
  • Reproductible : Il suffit de pointer Jenkins vers le SCM.
  • Robuste : Permet une logique complexe (try/catch, parallèle, conditions).
  • Partageable : (Via Shared Libraries).
Jenkinsfile (Exemple simple)
pipeline {
    agent any // Sur quel agent ?
    
    stages {
        stage('Build') {
            steps {
                sh 'npm install'
            }
        }
        stage('Test') {
            steps {
                sh 'npm test'
            }
        }
    }
}
3.2 Declarative vs Scripted Pipeline

Le Jenkinsfile peut être écrit dans deux syntaxes (basées sur Groovy) :

Critère1. Declarative Pipeline (Recommandé)2. Scripted Pipeline (Avancé)
SyntaxeStructurée, (similaire à YAML/JSON).Code Groovy pur. Très flexible.
Bloc racinepipeline { ... }node { ... }
Courbe d'apprentissageFacile à lire, structurée.Nécessite de connaître Groovy.
Logique complexeLimitée (script { ... } pour du Groovy).Illimitée (if, try/catch natifs).
Usage90% des cas. CI/CD standard.Logique très complexe, pipelines dynamiques.
3.3 Syntaxe Declarative (pipeline, agent, stages, post)
Squelette Jenkinsfile
// (Pas de 'node')
pipeline { // 1. Bloc racine
    
    agent any // 2. Où exécuter ? (n'importe quel agent)
    
    stages { // 3. Le "travail"
        
        stage('Build') { // 4. Une étape (colonne dans Blue Ocean)
            steps {
                // 5. Commandes à exécuter
                echo "Building..."
                sh 'npm install'
            }
        }
        
        stage('Test') {
            steps {
                sh 'npm test'
            }
        }
        
        stage('Deploy') {
            steps {
                echo "Deploying..."
            }
        }
    }
}
Directives de Pipeline
pipeline {
    // 1. Agent: Spécifier un label (défini sur l'Agent)
    // agent { label 'linux-docker' }
    
    // (ou un conteneur Docker)
    agent {
        docker { 
            image 'node:18-alpine'
            args '-v /tmp:/tmp'
        }
    }

    // 2. Tools: Outils définis dans "Manage Jenkins"
    tools {
        jdk 'jdk17'
        maven 'maven3'
    }
    
    // 3. Variables d'environnement
    environment {
        GREETING = "Hello ${env.BRANCH_NAME}"
        DB_PASS = credentials('db-password-id')
    }
    
    stages { ... }
}
Section post (Après les stages)

Permet d'exécuter des étapes à la fin du build (nettoyage, notifications).

pipeline {
    agent any
    stages { ... }
    
    post {
        // S'exécute toujours
        always {
            echo 'Cleanup...'
            deleteDir() // Nettoie le workspace
        }
        
        // Si succès
        success {
            echo 'Build OK !'
            slackSend(message: 'Success')
        }
        
        // Si échec
        failure {
            echo 'Build ÉCHOUÉ !'
            slackSend(message: 'FAILURE')
        }
        
        // Si statut a changé (ex: OK -> ÉCHEC)
        changed {
            echo 'Statut changé.'
        }
    }
}
3.4 Declarative Steps (steps)
Commandes de base (steps)
ÉtapeDescription
sh '...'Exécute un script Shell (Linux/macOS).
bat '...'Exécute un script Batch (Windows).
pwsh '...'Exécute PowerShell.
echo '...'Affiche un message dans le log.
error '...'Stoppe le build (statut FAILED).
deleteDir()Nettoie le workspace (rm -rf .).
Étapes de Plugins (Commun)
ÉtapeDescription (Plugin)
git '...'Clone un dépôt (Plugin Git).
archiveArtifacts '...'Archive des fichiers (JUnit).
junit '...'Publie les résultats de tests.
docker.build('...')Build une image (Docker Pipeline).
withCredentials(...)Injecte un secret (Credentials Binding).
stash / unstashPasse des fichiers entre les 'stages'.
Exemple de steps
steps {
    // 1. Script Shell (Multi-lignes)
    sh '''
      echo "Préparation..."
      echo "Branch: ${env.BRANCH_NAME}"
      npm install
    '''
    
    // 2. Archiver
    archiveArtifacts artifacts: 'build/app.jar', fingerprint: true
    
    // 3. Mettre dans un 'dir'
    dir('reports') {
        junit 'results.xml'
    }
}
3.5 Scripted Pipeline (Avancé)
Syntaxe Groovy

Le pipeline "Scripted" est du code Groovy pur. Il est plus puissant mais plus difficile à lire.

Il commence par node { } (l'équivalent de agent) et les étapes sont des stage { } (fonctions).

Exemple (Scripted)
node('linux') { // 1. Bloc 'node' (agent)
    try {
        
        stage('Checkout') {
            git 'https://github.com/...'
        }
        
        stage('Build & Test') {
            // Logique Groovy (boucles, conditions...)
            def nodeVersion = "node:18"
            
            docker.image(nodeVersion).inside {
                sh 'npm install'
                sh 'npm test'
            }
        }
        
        stage('Parallel Deploy') {
            // Exécuter en parallèle
            parallel(
                staging: {
                    stage('Deploy Staging') {
                        echo "Deploying to staging..."
                    }
                },
                qa: {
                    stage('Deploy QA') {
                        echo "Deploying to QA..."
                    }
                }
            )
        }
        
    } catch (e) {
        // Gérer les erreurs
        currentBuild.result = 'FAILURE'
        slackSend(message: "Échec: ${e.message}")
        throw e
    } finally {
        // Cleanup
        deleteDir()
    }
}
4.1 Shared Libraries (DRY)
Factoriser le code Pipeline

Problème : Vous avez 50 projets (50 Jenkinsfile) qui font tous la même chose (Build, Test, Deploy). Si vous devez changer l'étape "Deploy", vous devez modifier 50 fichiers.

Solution : Une "Shared Library" est un dépôt Git séparé qui contient votre logique de build (fonctions Groovy).

Manage Jenkins -> System -> Global Pipeline Libraries : Ajoutez votre dépôt (ex: jenkins-shared-lib).

Structure (Dépôt jenkins-shared-lib)
jenkins-shared-lib/
└── vars/
    ├── buildNodeApp.groovy
    └── notifySlack.groovy
vars/buildNodeApp.groovy
// Définit une fonction globale
def call(String nodeVersion = "18") {
    echo "Building Node App (v${nodeVersion})"
    
    docker.image("node:${nodeVersion}-alpine").inside {
        sh 'npm install'
        sh 'npm test'
    }
}
Utilisation (Jenkinsfile du projet)
// 1. Importer la librairie
@Library('jenkins-shared-lib@main') _

pipeline {
    agent any
    stages {
        stage('Build & Test') {
            steps {
                // 2. Appeler la fonction globale
                buildNodeApp(nodeVersion: "20")
            }
        }
        stage('Notify') {
            steps {
                notifySlack(message: "Build OK")
            }
        }
    }
}
4.2 Multibranch Pipeline (Indispensable)
1 Job par Branche

Un job "Pipeline" simple est lié à une seule branche (ex: main). C'est inutile pour le développement (feature, dev).

Un job "Multibranch Pipeline" scanne un dépôt Git (via Webhook) et crée/supprime automatiquement des jobs Jenkins pour *chaque branche* qui contient un Jenkinsfile.

Création
  1. New Item -> Multibranch Pipeline.
  2. Branch Sources : Add Source -> Git.
  3. Entrez l'URL du dépôt et les Credentials.
  4. Save.
Exemple de Jenkinsfile (Multibranch)
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'npm install'
            }
        }
        stage('Test') {
            steps {
                sh 'npm test'
            }
        }
        stage('Deploy Staging') {
            // Ne s'exécute que sur la branche 'dev'
            when { branch 'dev' }
            steps {
                echo "Deploying to STAGING..."
            }
        }
        stage('Deploy Prod') {
            // Ne s'exécute que sur 'main'
            when { branch 'main' }
            steps {
                // (Attend une approbation manuelle)
                input message: "Déployer en PROD ?"
                echo "Deploying to PRODUCTION..."
            }
        }
    }
}
4.3 Artifacts & Credentials (Secrets)
archiveArtifacts

Stocke des fichiers (ex: .jar, .war, .zip) à la fin du build, pour un téléchargement ou un déploiement ultérieur.

post {
    success {
        archiveArtifacts artifacts: 'build/libs/*.jar'
    }
}
stash / unstash

Passe des fichiers entre les stages (surtout si les agents sont différents).

stage('Build') {
    agent { label 'build-agent' }
    steps {
        sh 'npm run build'
        stash name: 'dist', includes: 'dist/**'
    }
}
stage('Deploy') {
    agent { label 'deploy-agent' }
    steps {
        unstash name: 'dist'
        // (Déployer le dossier 'dist')
    }
}
Gestion des Secrets (Credentials)

⚠️ Ne **jamais** écrire de mots de passe, tokens, ou clés SSH dans un Jenkinsfile.

Utilisez le Credentials Manager (Manage Jenkins -> Credentials) pour stocker les secrets.
Types : "Secret text", "Username with password", "SSH Username with private key".

Utilisation (withCredentials)

Le bloc withCredentials expose le secret (stocké sous un ID, ex: api-key-prod) en tant que variable d'environnement, masquée dans les logs.

stage('Deploy') {
    steps {
        // [MY_API_KEY] = 'Secret text' (ID: 'api-key-prod')
        withCredentials([string(credentialsId: 'api-key-prod', variable: 'MY_API_KEY')]) {
            
            // La variable $MY_API_KEY n'existe que ici
            sh 'deploy.sh --key ${env.MY_API_KEY}'
        }
    }
}
5.1 Blue Ocean (UI Moderne)
Une UI pour les Pipelines

L'interface "classique" de Jenkins est dense et peu adaptée à la visualisation des stages (Build, Test, Deploy) d'un Pipeline.

Blue Ocean est un plugin (souvent installé par défaut) qui offre une interface utilisateur moderne, visuelle et interactive, dédiée aux Pipelines (Multibranch ou non).

Accès : http://jenkins:8080/blue

Visualisation claire des stages (surtout parallel), accès direct aux logs par étape, et ré-exécution d'un stage spécifique.

6.1 Cheat-sheet (Declarative Jenkinsfile)
Squelette Declarative
pipeline {
    // 1. Agent (Où ?)
    agent any
    // agent { label 'linux' }
    // agent { docker { image 'node:18' } }
    
    // 2. Outils (Java, Maven, Node...)
    tools {
        jdk 'jdk17'
    }
    
    // 3. Variables d'Environnement
    environment {
        MY_VAR = "valeur"
        SECRET = credentials('mon-secret-id')
    }
    
    // 4. Paramètres (Build 'with parameters')
    parameters {
        string(name: 'VERSION', defaultValue: '1.0', description: 'Version')
        booleanParam(name: 'DO_DEPLOY', defaultValue: false)
    }

    // 5. Triggers
    triggers {
        cron('H/15 * * * *') // Tous les 15 min
    }

    // 6. Étapes
    stages {
        stage('Checkout') {
            steps {
                git 'https://github.com/...'
            }
        }
        
        stage('Build & Test') {
            when { branch 'main' } // Condition
            steps {
                sh 'npm install'
                sh 'npm test'
            }
        }
        
        stage('Package') {
            steps {
                sh 'npm run build'
                // Stash pour le prochain stage
                stash name: 'dist', includes: 'dist/**'
            }
        }
    }
    
    // 7. Post-Build
    post {
        always {
            junit 'reports/*.xml'
            archiveArtifacts 'build/*.zip'
        }
        failure {
            slackSend(message: "ÉCHEC: ${env.JOB_NAME} build ${env.BUILD_NUMBER}")
        }
    }
}