Les jobs Freestyle de Jenkins sont bien pour débuter, mais en production ils ne tiennent pas : pas versionnés, pas reproductibles, pas reviewables. Le Pipeline as Code résout tout ça — tu décris ton CI/CD dans un fichier Jenkinsfile versionné dans ton repo Git. C’est la base de tout Jenkins moderne.
Pipeline déclaratif : la syntaxe complète
Le pipeline déclaratif est le format recommandé. Sa structure est rigide mais lisible — parfait pour les équipes. Voici le squelette complet :
pipeline {
agent any
environment {
APP_NAME = 'mon-app'
GIT_HASH = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
DOCKER_CREDS = credentials('docker-hub-creds')
}
options {
timeout(time: 30, unit: 'MINUTES')
buildDiscarder(logRotator(numToKeepStr: '10'))
timestamps()
disableConcurrentBuilds()
}
parameters {
choice(name: 'ENVIRONMENT', choices: ['staging', 'production'], description: 'Cible')
booleanParam(name: 'SKIP_TESTS', defaultValue: false, description: 'Passer les tests')
}
stages {
stage('Build') {
steps {
sh 'npm ci'
sh 'npm run build'
}
}
stage('Test') {
steps {
sh 'npm test -- --coverage'
}
post {
always { junit 'reports/**/*.xml' }
}
}
stage('Deploy') {
when { branch 'main' }
steps {
sh "./deploy.sh ${params.ENVIRONMENT}"
}
}
}
post {
success { slackSend color: 'good', message: "✅ ${env.JOB_NAME} #${env.BUILD_NUMBER} OK" }
failure { slackSend color: 'danger', message: "❌ ${env.JOB_NAME} #${env.BUILD_NUMBER} FAILED" }
always { cleanWs() }
}
}
💡 Chaque section a un rôle précis : environment pour les variables, options pour le comportement global, parameters pour rendre le pipeline interactif, stages pour les étapes, et post pour les actions conditionnelles après l’exécution.
Agent : où ça tourne
L’agent définit l’environnement d’exécution. Tu peux l’assigner globalement ou par stage — c’est ce qui donne à Jenkins sa flexibilité.
// N'importe quel agent disponible
agent any
// Agent avec label (ex: machine avec Docker)
agent { label 'linux && docker' }
// Conteneur Docker (isolé, reproductible)
agent {
docker {
image 'node:20-alpine'
args '-v /tmp:/tmp'
}
}
// Pod Kubernetes (éphémère, scalable)
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: node
image: node:20
command: ['sleep', 'infinity']
'''
}
}
🔥 En production, utilise agent { docker { ... } } ou agent { kubernetes { ... } } pour l’isolation. Un agent any sur un nœud partagé finit toujours par créer des conflits de dépendances entre projets.
When : exécution conditionnelle des stages
La directive when contrôle si un stage s’exécute. C’est indispensable pour les pipelines multi-branches.
stages {
stage('Deploy Staging') {
when { branch 'develop' }
steps { sh './deploy.sh staging' }
}
stage('Deploy Production') {
when {
allOf {
branch 'main'
not { changeRequest() }
}
}
steps { sh './deploy.sh production' }
}
stage('Tagged Release') {
when {
tag pattern: 'v\\d+\\.\\d+\\.\\d+', comparator: 'REGEXP'
}
steps { sh './release.sh' }
}
stage('Feature Test') {
when {
expression { return params.SKIP_TESTS == false }
}
steps { sh 'npm test' }
}
}
⚠️ Sans when, chaque stage s’exécute systématiquement. Sur un Multibranch Pipeline, ça veut dire que ta feature branch tente de déployer en prod — pas idéal.
Pipeline complet : app Node.js réaliste
Voici un Jenkinsfile production-ready qui build, test, push une image Docker, et déploie :
pipeline {
agent none
environment {
REGISTRY = 'registry.company.com'
IMAGE = 'mon-app'
}
stages {
stage('Quality') {
parallel {
stage('Lint') {
agent { docker { image 'node:20-alpine' } }
steps {
sh 'npm ci && npm run lint'
}
}
stage('Unit Tests') {
agent { docker { image 'node:20-alpine' } }
steps {
sh 'npm ci && npm test -- --coverage'
}
post {
always { junit 'reports/junit.xml' }
}
}
stage('Security') {
agent { docker { image 'node:20-alpine' } }
steps {
sh 'npm ci && npm audit --audit-level=high'
}
}
}
}
stage('Build & Push Image') {
agent { label 'docker' }
steps {
script {
def tag = "${BUILD_NUMBER}-${GIT_COMMIT.take(7)}"
withCredentials([usernamePassword(
credentialsId: 'registry-creds',
usernameVariable: 'USER',
passwordVariable: 'PASS'
)]) {
sh """
docker build -t ${REGISTRY}/${IMAGE}:${tag} .
echo \$PASS | docker login ${REGISTRY} -u \$USER --password-stdin
docker push ${REGISTRY}/${IMAGE}:${tag}
"""
}
env.IMAGE_TAG = tag
}
}
}
stage('Deploy') {
agent { label 'kubectl' }
when { branch 'main' }
steps {
sh "kubectl set image deployment/${IMAGE} app=${REGISTRY}/${IMAGE}:${env.IMAGE_TAG}"
}
}
}
post {
success { slackSend color: 'good', message: "✅ ${JOB_NAME} #${BUILD_NUMBER}" }
failure { slackSend color: 'danger', message: "❌ ${JOB_NAME} #${BUILD_NUMBER}" }
}
}
🎯 Note le parallel dans le stage Quality — lint, tests et audit de sécurité tournent en même temps. Sur un pipeline de 10 minutes, ça peut te faire gagner 5 minutes de feedback.
Multibranch Pipeline : un pipeline par branche
Le Multibranch Pipeline scanne ton repo Git, détecte toutes les branches avec un Jenkinsfile, et crée automatiquement un pipeline par branche. C’est le type de job à utiliser en production.
Configuration : New Item → Multibranch Pipeline → Branch Sources : ton repo Git → Build Configuration : Jenkinsfile. Jenkins scanne et crée :
mon-projet/
├── main → pipeline de la branche main
├── develop → pipeline de la branche develop
├── feature/auth → pipeline de la feature branch
└── PR-42 → pipeline de la Pull Request #42
Chaque branche a son historique de builds indépendant. Les branches supprimées = pipelines nettoyés automatiquement.
💡 Configure un webhook GitHub/GitLab plutôt que le polling SCM. Le polling toutes les minutes génère du trafic inutile et ajoute du délai. Le webhook déclenche le build instantanément au push.
Cas entreprise, pièges et résumé
Une équipe de 15 développeurs avait 45 jobs Freestyle Jenkins. Chaque job était configuré manuellement dans l’UI — pas de versioning, pas de review. Un jour, le serveur Jenkins a crashé. La restauration du backup a pris 4 heures, et 8 jobs avaient des configs corrompues.
Leur migration vers Pipeline as Code :
- Semaine 1 : conversion des 10 jobs les plus critiques en Jenkinsfiles déclaratifs
- Semaine 2 : passage en Multibranch Pipeline avec webhook GitHub
- Semaine 3 : ajout de stages parallèles (lint + test + security scan)
- Résultat : temps de feedback moyen passé de 18 min à 7 min, zéro perte de config possible (tout est dans Git)
Les pièges à éviter :
⚠️ Le Replay abusé — Jenkins permet de rejouer un build avec un Jenkinsfile modifié sans commit. Pratique pour débugger, mais certaines équipes l’utilisent comme workflow permanent. Résultat : le Jenkinsfile dans Git ne correspond plus à ce qui tourne vraiment. Utilise Replay uniquement pour le debug, puis commit la correction.
⚠️ Les credentials dans les logs — Un sh "echo ${DOCKER_PASSWORD}" affiche le mot de passe en clair dans les logs. Utilise toujours withCredentials ou credentials() dans le bloc environment — Jenkins les masque automatiquement.
🔥 Valide avant de push — L’API Jenkins peut valider la syntaxe de ton Jenkinsfile :
curl -X POST -F "jenkinsfile=<Jenkinsfile" \
http://jenkins.company.com/pipeline-model-converter/validate
⚠️ Blue Ocean en maintenance — Blue Ocean offre une UI moderne mais est en maintenance mode depuis 2023. Utilise-le pour la visualisation, pas comme outil principal. L’UI classique reste la référence pour la config.
Le Pipeline as Code transforme Jenkins d’un outil fragile en une solution robuste. Le Jenkinsfile déclaratif couvre 90% des besoins : agent pour l’environnement, stages pour les étapes, when pour les conditions, post pour les actions post-build, et parallel pour la vitesse. Le Multibranch Pipeline automatise la gestion des branches. Versionne tout dans Git — ton CI/CD devient aussi auditable que ton code.
🖥️ Pratique sur ton propre serveur
Pour suivre Jenkins en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.
Contenu réservé aux abonnés
Ce chapitre fait partie de la formation complète. Abonne-toi pour débloquer tous les contenus.
Débloquer pour 29 CHF/moisLe chapitre 1 de chaque formation est gratuit.
Série pas encore débloquée
Termine la série prérequise d'abord pour accéder à ce contenu.
Aller à la série prérequiseSérie : Jenkins
2 / 8- Jenkins #1 — Introduction : Pourquoi Jenkins, Architecture et Premier Job
- 2 Jenkins #2 — Premier Pipeline : Jenkinsfile et Pipeline Déclaratif
- 3 Jenkins #3 — Pipeline Avancé : Scripté, Shared Libraries et Parallel Stages
- 4 Jenkins #4 — Plugins Essentiels : Docker, K8s, Git, SonarQube et Slack
- 5 Jenkins #5 — Jenkins et Docker : Build d'Images, DinD et Kaniko
- 6 Jenkins #6 — Jenkins sur Kubernetes : Helm, Pod Templates et Scaling
- 7 Jenkins #7 — Sécurité : RBAC, Credentials, Audit Trail et Hardening
- 8 Jenkins #8 — Production : HA, Backup, Monitoring et Migration
Sur cette page
Articles liés
Jenkins #1 — Introduction : Pourquoi Jenkins, Architecture et Premier Job
Découvre Jenkins de A à Z : pourquoi c'est le standard CI/CD, l'architecture master/agent, l'installation sur Ubuntu et ton premier job freestyle.
Jenkins #3 — Pipeline Avancé : Scripté, Shared Libraries et Parallel Stages
Maîtrise les pipelines Jenkins avancés : scripté vs déclaratif, shared libraries, stages parallèles, input/approval et patterns de production.
Jenkins #4 — Plugins Essentiels : Docker, K8s, Git, SonarQube et Slack
Tour d'horizon des plugins Jenkins incontournables : Docker, Kubernetes, Git, SonarQube, Slack, credentials binding et leur configuration complète.