« Le pipeline se configure dans l’interface de Jenkins, en cliquant. »
L’approche moderne est inverse : le pipeline est un fichier versionné dans le dépôt — le Jenkinsfile. Il vit avec le code, évolue avec lui, se relit et se restaure comme lui. C’est le principe pipeline-as-code, et il vaut pour tous les outils CI/CD.
À la fin de ce module, tu sauras…
- Écrire un Jenkinsfile déclaratif, stage par stage
- Taguer chaque image avec le commit Git (traçabilité)
- Donner à Jenkins l’identité Harbor (credential robot)
- Créer le job Pipeline et prouver la première exécution
01Le Jenkinsfile, stage par stage
Écrire la séquence — celle que tu faisais à la main
À la racine de ton dépôt soria-web (sur mgmt), crée le fichier Jenkinsfile :
pipeline {
agent any
environment {
REGISTRY = 'harbor.mondomaine.fr'
PROJECT = 'soria'
IMAGE_NAME = 'soria-web'
IMAGE_REPO = "${REGISTRY}/${PROJECT}/${IMAGE_NAME}"
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Compute Tag') {
steps {
script {
def shortSha = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
env.IMAGE_TAG = "gitsha-${shortSha}"
env.FULL_IMAGE = "${env.IMAGE_REPO}:${env.IMAGE_TAG}"
echo "Image will be: ${env.FULL_IMAGE}"
}
}
}
stage('Build') {
steps {
sh '''
set -eu
docker build -t "$FULL_IMAGE" .
'''
}
}
stage('Login Harbor') {
steps {
withCredentials([usernamePassword(
credentialsId: 'harbor-robot-soria',
usernameVariable: 'HARBOR_USER',
passwordVariable: 'HARBOR_TOKEN'
)]) {
sh '''
set -eu
echo "$HARBOR_TOKEN" | docker login "$REGISTRY" -u "$HARBOR_USER" --password-stdin
'''
}
}
}
stage('Push') {
steps {
sh '''
set -eu
docker push "$FULL_IMAGE"
docker image inspect "$FULL_IMAGE" --format '{{index .RepoDigests 0}}'
'''
}
}
}
post {
always {
sh 'docker logout "$REGISTRY" || true'
}
}
}Comprends l’anatomie, bloc par bloc
pipeline{} = le pipeline déclaratif ; agent any = sur quelle machine exécuter ; environment{} = les variables partagées ; chaque stage{} = une étape nommée, visible dans l’interface ; steps > sh = exactement tes commandes manuelles ; post > always = nettoyage, même en cas d’échec (on ne laisse pas une session registre ouverte). Reconnais ta séquence de la Phase 3-4 : le pipeline n’invente rien, il rejoue.
02Le tag qui trace tout
Compute Tag : chaque image est taguée gitsha-<sha> — le hash du commit qui l’a produite.Comprends pourquoi pas latest, ni 2.1 à la main
Le tag gitsha-e68de40 relie l’image au commit exact qui l’a produite : traçabilité totale (quelle version tourne ? → quel commit ?), pas d’écrasement (chaque commit = un tag unique), et rollback précis. Le tag manuel (2.1) dépend de ta discipline ; le tag calculé est garanti par la machine. Concept universel : dans tout outil CI, l’artefact est identifié par la révision du code.
03L’identité Harbor de Jenkins
Le credential du compte robot
Le pipeline référence credentialsId: ‘harbor-robot-soria’ — créons-le. Dans Jenkins → Manage Jenkins → Credentials → (global) → Add Credentials :
| Champ | Valeur |
|---|---|
| Kind | Username with password |
| ID | harbor-robot-soria |
| Username | robot$soria+ci (le robot de la Phase 4) |
| Password | le token du robot |
withCredentials : le token n’apparaît jamais dans le Jenkinsfile ni dans les logs (Jenkins le masque).Comprends withCredentials, le pattern
withCredentials injecte le secret en variables d’environnement seulement pendant le bloc, puis les efface. Combiné à –password-stdin (le token ne passe pas en argument de commande, donc pas dans l’historique), c’est le pattern standard : secret dans le coffre → référencé par ID → injecté temporairement. Le même schéma existe partout (GitLab CI : variables masquées ; GitHub Actions : secrets).
04Créer le job & première exécution
Relier Jenkins au dépôt, et lancer
Commit et push le Jenkinsfile, puis dans Jenkins → New Item :
- Name :
soria-web-ci· Type : Pipeline - Section Pipeline → Definition : Pipeline script from SCM
- SCM : Git · Repository URL :
git@github.com:ton-compte/soria-web.git - Credentials :
github-soria-ssh(module 6.1) · Branch :*/main· Script Path :Jenkinsfile
Sauvegarde, puis clique Build Now et ouvre le Console Output.
ObserveImage will be: harbor.mondomaine.fr/soria/soria-web:gitsha-e68de40
...
Login Succeeded
...
harbor.mondomaine.fr/soria/soria-web@sha256:...gitsha-… apparaît dans le projet soria. Jenkins vient de faire, seul, ce que tu faisais à la main.Comprends « Pipeline script from SCM »
Jenkins ne stocke pas le pipeline : il va le chercher dans le dépôt à chaque exécution. Le Jenkinsfile est donc versionné, relu en revue de code, et restaurable — comme le reste du code. C’est le cœur du pipeline-as-code : l’automatisation elle-même est du code.
✓Ce que tu retiens
Le pipeline est un fichier versionné (pipeline-as-code) qui rejoue ta séquence manuelle en stages : checkout → tag calculé (gitsha-…, traçabilité commit ↔ image) → build → login (credential robot, jamais en clair) → push. Jenkins produit désormais un artefact fiable et tracé à chaque exécution — la moitié CI de la chaîne.
Ta première chaîne CI — plus un défi sécurité
À faire
- Écris le Jenkinsfile, commit, push.
- Crée le credential
harbor-robot-soriaet le jobsoria-web-ci. - Lance Build Now, lis chaque stage dans le Console Output.
- Prouve dans Harbor le nouveau tag
gitsha-…et son digest. - Défi (sécurité supply chain) : ajoute un stage
Scanqui analyse l’image avec Trivy avant le push, et fait échouer le pipeline en cas de vulnérabilité critique. Indices : Trivy s’installe en binaire sur la VM Jenkins ;trivy image –exit-code 1 –severity CRITICAL “$FULL_IMAGE”; place le stage entre Build et Login. Tu peux aussi comparer avec le scan automatique côté Harbor (Phase 4).
?Auto-évaluation
1. Pourquoi le Jenkinsfile vit-il dans le dépôt et pas dans Jenkins ?
Pipeline-as-code : versionné, revu, restaurable avec le code. Jenkins le relit depuis le dépôt à chaque exécution.
2. Quel est l’intérêt du tag gitsha-<sha> ?
Il relie chaque image au commit exact qui l’a produite : traçabilité, unicité, rollback précis — sans dépendre de la discipline humaine.
3. Comment le token Harbor reste-t-il hors des logs ?
withCredentials l’injecte temporairement et Jenkins le masque ; –password-stdin évite qu’il apparaisse en argument de commande.