Aller au contenu
CI/CD & Automatisation medium

Lab 12, Accélérer le pipeline

10 min de lecture

logo gitlab

Un pipeline lent finit par coûter cher : attente développeur, review ralentie, files runners saturées. Dans ce lab, vous optimisez les points qui apportent le plus de gains sans complexifier inutilement le YAML : cache bien clés, images allégées et parallélisme contrôlé.

  • Choisir une clé de cache stable et pertinente
  • Éviter les caches inutilisables ($CI_COMMIT_SHA)
  • Utiliser needs pour lancer des jobs en parallèle
  • Mesurer l'impact réel des optimisations

Ce lab s'appuie sur les acquis du Lab 11. Si vous maîtrisez déjà le diagnostic de pipeline, vous pouvez démarrer ici avec starter/lab-12.

Les pipelines lents sont un problème de productivité avant d'être un problème technique. Si chaque push met 8 minutes, les développeurs poussent moins souvent et accumulent des changements plus gros, ce qui augmente le risque de conflit et d'erreur.

Ce lab répond à des cas fréquents :

  • cache jamais réutilisé à cause d'une clé trop spécifique
  • jobs indépendants bloqués par la logique de stage séquentielle
  • images trop lourdes téléchargées à chaque run
  1. Basculez sur la branche du lab

    Fenêtre de terminal
    cd pipeline-craft
    git checkout starter/lab-12
  2. Lancez un run de référence

    Fenêtre de terminal
    git push origin starter/lab-12
  3. Notez la durée du pipeline

    Cette valeur sert de baseline avant optimisation.

La lenteur vient souvent de trois causes combinées :

  • cache inexploitable
  • exécution trop séquentielle
  • images ou builds non optimisés

Vous allez corriger ces trois zones sans rendre le pipeline illisible.

Étape 1, À vous de corriger la stratégie de cache

Section intitulée « Étape 1, À vous de corriger la stratégie de cache »
  1. Remplacez une clé de cache instable par une clé basée sur les fichiers de dépendances.

  2. Vérifiez sur deux runs successifs : le second doit restaurer le cache.

    Indice : une clé par commit empêche la réutilisation du cache.

👉 Vérifier votre solution (Étape 1)

Avant (clé instable, jamais réutilisée) :

cache:
key: "$CI_COMMIT_SHA" # ❌ Change à chaque commit
paths:
- .pip-cache/

Après (clé stable, réutilisée quand les dépendances ne changent pas) :

cache:
key:
files:
- requirements-dev.txt
paths:
- .pip-cache/

La clé change uniquement quand requirements-dev.txt est modifié.

Vérification dans les logs du job :

  • 1er run : Uploading cache.zip to https://... (création)
  • 2e run : Downloading cache.zip from https://... (restauration ✅)
  1. Identifiez les jobs indépendants.

  2. Ajoutez des needs explicites si nécessaire pour activer le DAG.

    Cette approche réduit l'attente artificielle liée aux stages.

👉 Vérifier votre solution (Étape 2)

Sans needs, les stages s'exécutent en séquence stricte. Avec needs, chaque job démarre dès que ses dépendances sont satisfaites :

pytest:
stage: test
needs: [] # ✅ Démarre dès que possible, sans attendre lint

Graphe d'exécution :

  • Avant : ruff-lint fini → pytest démarre → docker-build démarre
  • Après : ruff-lint et pytest démarrent en parallèle grâce à needs: [] sur pytest

Étape 3, À vous de vérifier les images utilisées

Section intitulée « Étape 3, À vous de vérifier les images utilisées »
  1. Confirmez l'usage de variantes allégées (python:3.12-slim)

  2. Gardez docker:27 uniquement pour les jobs qui en ont besoin

    Chaque job doit utiliser l'image minimale adaptée à son besoin.

👉 Vérifier votre solution (Étape 3)
Type de jobImage recommandéeÀ éviter
Lint Pythonpython:3.12-slimpython:3.12 (+200 MB inutiles)
Tests Pythonpython:3.12-slimubuntu:22.04 (outils inutiles)
Build Dockerdocker:27 + docker:27-dindImage Docker + OS complet
Deploy simplealpine:3.20Image Debian ou Ubuntu

La variante slim d'une image Python coûte généralement 3 à 4 fois moins en temps de pull que la variante standard. alpine:3.20 pèse moins de 10 MB.

  1. Poussez votre optimisation

    Fenêtre de terminal
    git add .gitlab-ci.yml
    git commit -m "ci: speed up pipeline with cache and dag"
    git push origin starter/lab-12
  2. Comparez la durée avec la baseline

    Vous devez observer une réduction tangible dès le second run optimisé.

👉 Vérifier votre solution (Étape 4)

Méthode : notez la colonne duration dans la liste des pipelines avant et après optimisation.

Gains typiques :

OptimisationGain attendu
Cache restauré-30 à 60 sec
needs sur jobs indépendants-durée du stage le plus court
Image slim vs standard-10 à 30 sec de pull

Mesurez sur 2 à 3 runs consécutifs : le premier run alimente le cache, les suivants le réutilisent. C'est à partir du deuxième run que le gain est visible.

📄 Voir le fichier .gitlab-ci.yml complet
stages:
- lint
- test
- build
- deploy
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "push"
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_TAG
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.pip-cache"
ruff-lint:
stage: lint
image: python:3.12-slim
cache:
key:
files:
- requirements-dev.txt
paths:
- .pip-cache/
policy: pull
before_script:
- pip install ruff
script:
- ruff check app/ tests/
pytest:
stage: test
image: python:3.12-slim
needs: []
cache:
key:
files:
- requirements-dev.txt
paths:
- .pip-cache/
before_script:
- pip install -r requirements-dev.txt
script:
- pytest -v --junitxml=report.xml --cov=app --cov-report=term-missing
coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
artifacts:
when: always
paths:
- report.xml
reports:
junit: report.xml
expire_in: 7 days
docker-build:
stage: build
image: docker:27
services:
- docker:27-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
- docker build -t $CI_REGISTRY_IMAGE:latest .
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- docker push $CI_REGISTRY_IMAGE:latest
deploy-staging:
stage: deploy
image: alpine:3.20
script:
- echo "Deploying $CI_COMMIT_SHORT_SHA to staging..."
- ./scripts/deploy-demo.sh staging
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
deploy-production:
stage: deploy
image: alpine:3.20
script:
- echo "Deploying $CI_COMMIT_SHORT_SHA to production..."
- ./scripts/deploy-demo.sh production
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual
  • Le cache est restauré sur un run suivant
  • Les jobs indépendants ne s'attendent plus inutilement
  • Le pipeline total est sensiblement plus court
  • Le YAML reste lisible et maintenable

Un pipeline très optimisé mais illisible devient vite un problème de maintenance. Cherchez un équilibre entre performance et clarté.

Autre piège : annoncer un gain après un seul run. Le premier run sert souvent à alimenter le cache. Mesurez au minimum sur deux à trois exécutions comparables.

  • Une bonne clé de cache change quand les dépendances changent, pas à chaque commit
  • Le DAG (needs) réduit l'attente artificielle des stages
  • Les images allégées accélèrent le pull et donc le pipeline
  • Mesurer avant/après est indispensable pour valider une optimisation

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn