Pipeline CI/CD : automatiser le déploiement

🏷️ Cloud && Déploiement 📅 14/04/2026 17:00:00 👤 Mezgani said
Ci Cd Pipeline Integration Continue Deploiement Continu Devops Gitlab Ci
Pipeline CI/CD : automatiser le déploiement

Maîtrisez les pipelines CI/CD pour automatiser le build, les tests et le déploiement de vos applications. Concepts, étapes, outils populaires, bonnes pratiques et exemple de pipeline complet avec GitLab CI.

Qu'est-ce que CI/CD ?

CI/CD (Continuous Integration / Continuous Deployment) est un ensemble de pratiques DevOps qui permettent d'automatiser le processus de livraison logicielle, de la compilation du code jusqu'au déploiement en production.

Continuous Integration (CI)

L'intégration continue consiste à fusionner fréquemment (plusieurs fois par jour) les modifications de code dans une branche principale, et à exécuter automatiquement des tests pour détecter les régressions rapidement.

Continuous Delivery (CD)

La livraison continue garantit que le code est toujours dans un état déployable. Chaque changement validé peut être déployé en production sur simple approbation manuelle.

Continuous Deployment (CD)

Le déploiement continu va plus loin : chaque changement validé par les tests est automatiquement déployé en production sans intervention humaine.

🔄 En résumé :
  • CI : Build + Test automatique à chaque commit
  • Continuous Delivery : CI + Déploiement manuel vers prod
  • Continuous Deployment : CI + Déploiement automatique vers prod

Concepts fondamentaux

Pipeline

Un pipeline est un ensemble d'étapes automatisées qui transforment le code source en application déployée. Chaque étape (stage) contient des tâches (jobs) qui s'exécutent séquentiellement ou en parallèle.

Build

Le build compile le code source, installe les dépendances et génère les artefacts (fichiers exécutables, images Docker, bundles JavaScript, etc.).

Test

Les tests automatisés vérifient que le code fonctionne correctement :

  • Tests unitaires : Testent des fonctions isolées
  • Tests d'intégration : Testent l'interaction entre composants
  • Tests end-to-end (E2E) : Simulent un parcours utilisateur complet

Artefact

Un artefact est le résultat du build : fichier JAR, image Docker, bundle JavaScript, package npm, etc. Il est versionné et stocké pour être déployé.

Environnement

Les environnements représentent les différentes étapes du cycle de vie :

  • Development : Environnement local du développeur
  • Staging / Pre-production : Réplique de la production pour tests
  • Production : Environnement accessible aux utilisateurs finaux

Étapes typiques d'un pipeline

1. Source / Checkout

Récupération du code source depuis le dépôt Git (GitHub, GitLab, Bitbucket).

git clone https://github.com/user/mon-projet.git
git checkout main

2. Build

Compilation et installation des dépendances.

# Node.js
npm ci
npm run build

# Java Maven
mvn clean package

# Docker
docker build -t mon-app:latest .

3. Test

Exécution des tests automatisés.

# Tests unitaires
npm run test:unit

# Tests d'intégration
npm run test:integration

# Tests E2E
npm run test:e2e

# Analyse de code (linting)
npm run lint

# Couverture de code
npm run coverage

4. Code Quality

Analyse statique du code (SonarQube, ESLint, etc.).

# Analyse SonarQube
sonar-scanner \
  -Dsonar.projectKey=mon-projet \
  -Dsonar.sources=src \
  -Dsonar.host.url=https://sonar.example.com

5. Security Scan

Détection de vulnérabilités dans les dépendances.

# Audit npm
npm audit

# Scan Docker
docker scan mon-app:latest

# OWASP Dependency-Check
dependency-check --project mon-app --scan .

6. Package / Artifact

Création et stockage de l'artefact déployable.

# Push Docker image
docker tag mon-app:latest registry.example.com/mon-app:1.2.3
docker push registry.example.com/mon-app:1.2.3

# Publish npm package
npm publish

# Upload artifact
aws s3 cp dist/ s3://artifacts/mon-app/1.2.3/ --recursive

7. Deploy

Déploiement vers l'environnement cible.

# Kubernetes
kubectl set image deployment/mon-app mon-app=registry.example.com/mon-app:1.2.3
kubectl rollout status deployment/mon-app

# AWS
aws ecs update-service --cluster prod --service mon-app --force-new-deployment

# SSH
scp -r dist/ user@server:/var/www/mon-app/
ssh user@server 'systemctl restart mon-app'

8. Post-deployment Tests

Vérification que l'application fonctionne en production.

# Smoke tests
curl https://mon-app.com/health
curl https://mon-app.com/api/status

# Tests de performance
ab -n 1000 -c 10 https://mon-app.com/

Outils CI/CD populaires

Solutions hébergées (SaaS)

Outil Description Points forts
GitHub Actions CI/CD intégré à GitHub Intégration native, marketplace d'actions
GitLab CI/CD CI/CD intégré à GitLab Pipeline as code, auto DevOps
CircleCI Plateforme CI/CD cloud Performance, cache intelligent
Travis CI CI/CD pour projets open source Gratuit pour projets publics
Azure Pipelines CI/CD Microsoft Azure Intégration écosystème Microsoft

Solutions auto-hébergées

Outil Description Points forts
Jenkins Serveur CI/CD open source Flexible, 1800+ plugins
TeamCity CI/CD de JetBrains Interface intuitive, gratuit jusqu'à 100 builds
Drone CI/CD containerisé Léger, basé sur Docker
Bamboo CI/CD d'Atlassian Intégration Jira/Bitbucket

Exemple : GitLab CI/CD

GitLab CI/CD utilise un fichier .gitlab-ci.yml à la racine du projet.

Pipeline complet Node.js + Docker + Kubernetes

# .gitlab-ci.yml
variables:
  DOCKER_IMAGE: registry.gitlab.com/$CI_PROJECT_PATH
  DOCKER_TAG: $CI_COMMIT_SHORT_SHA

stages:
  - build
  - test
  - package
  - deploy

# Stage 1 : Build
build:
  stage: build
  image: node:18-alpine
  cache:
    paths:
      - node_modules/
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour

# Stage 2 : Tests en parallèle
test:unit:
  stage: test
  image: node:18-alpine
  dependencies:
    - build
  script:
    - npm ci
    - npm run test:unit
  coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

test:integration:
  stage: test
  image: node:18-alpine
  services:
    - postgres:15-alpine
  variables:
    POSTGRES_DB: test
    POSTGRES_USER: test
    POSTGRES_PASSWORD: test
  dependencies:
    - build
  script:
    - npm ci
    - npm run test:integration

test:lint:
  stage: test
  image: node:18-alpine
  script:
    - npm ci
    - npm run lint

test:security:
  stage: test
  image: node:18-alpine
  script:
    - npm audit --audit-level=moderate
  allow_failure: true

# Stage 3 : Package Docker
package:
  stage: package
  image: docker:latest
  services:
    - docker:dind
  dependencies:
    - build
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $DOCKER_IMAGE:$DOCKER_TAG -t $DOCKER_IMAGE:latest .
    - docker push $DOCKER_IMAGE:$DOCKER_TAG
    - docker push $DOCKER_IMAGE:latest
  only:
    - main
    - develop

# Stage 4 : Deploy Staging
deploy:staging:
  stage: deploy
  image: bitnami/kubectl:latest
  environment:
    name: staging
    url: https://staging.mon-app.com
  script:
    - kubectl config use-context staging-cluster
    - kubectl set image deployment/mon-app mon-app=$DOCKER_IMAGE:$DOCKER_TAG -n staging
    - kubectl rollout status deployment/mon-app -n staging
  only:
    - develop

# Stage 4 : Deploy Production (manuel)
deploy:production:
  stage: deploy
  image: bitnami/kubectl:latest
  environment:
    name: production
    url: https://mon-app.com
  script:
    - kubectl config use-context prod-cluster
    - kubectl set image deployment/mon-app mon-app=$DOCKER_IMAGE:$DOCKER_TAG -n production
    - kubectl rollout status deployment/mon-app -n production
  when: manual
  only:
    - main

Runners GitLab

Les runners exécutent les jobs du pipeline. Installez un runner sur votre serveur :

# Installation du runner
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt-get install gitlab-runner

# Enregistrement du runner
sudo gitlab-runner register \
  --url https://gitlab.com/ \
  --registration-token YOUR_TOKEN \
  --executor docker \
  --docker-image docker:latest

Exemple : GitHub Actions

GitHub Actions utilise des fichiers YAML dans .github/workflows/.

Pipeline CI/CD complet

# .github/workflows/ci-cd.yml
name: CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

env:
  NODE_VERSION: '18'
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/
          retention-days: 1

  test:
    runs-on: ubuntu-latest
    needs: build
    strategy:
      matrix:
        test-type: [unit, integration, e2e]
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/

      - name: Run ${{ matrix.test-type }} tests
        run: npm run test:${{ matrix.test-type }}

      - name: Upload coverage
        if: matrix.test-type == 'unit'
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/lcov.info

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: npm ci
      - run: npm run lint

  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: npm audit --audit-level=moderate

  docker:
    runs-on: ubuntu-latest
    needs: [build, test, lint]
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=sha,prefix={{branch}}-
            type=semver,pattern={{version}}
            type=raw,value=latest,enable={{is_default_branch}}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

  deploy:
    runs-on: ubuntu-latest
    needs: docker
    if: github.ref == 'refs/heads/main'
    environment:
      name: production
      url: https://mon-app.com
    steps:
      - name: Deploy to Kubernetes
        uses: azure/k8s-deploy@v4
        with:
          manifests: |
            k8s/deployment.yaml
            k8s/service.yaml
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
          namespace: production

Secrets GitHub

Stockez les secrets dans Settings → Secrets and variables → Actions :

  • DOCKER_USERNAME
  • DOCKER_PASSWORD
  • KUBE_CONFIG
  • AWS_ACCESS_KEY_ID

Stratégies de déploiement

Blue-Green Deployment

Deux environnements identiques (Blue et Green). Le nouveau code est déployé sur l'environnement inactif, puis le trafic bascule instantanément.

✅ Avantages : Rollback instantané, zéro downtime
❌ Inconvénients : Coûteux (double infrastructure)

Canary Deployment

Le nouveau code est déployé progressivement : d'abord 5% du trafic, puis 25%, puis 50%, jusqu'à 100%.

✅ Avantages : Détection précoce de bugs, impact limité
❌ Inconvénients : Complexe à mettre en place

Rolling Deployment

Les instances sont mises à jour progressivement, une par une ou par batch.

✅ Avantages : Pas de downtime, économique
❌ Inconvénients : Durée de déploiement plus longue

Feature Flags

Les nouvelles fonctionnalités sont déployées mais désactivées par défaut, puis activées progressivement via configuration.

// Exemple avec LaunchDarkly
const client = LaunchDarkly.initialize('sdk-key');

if (client.variation('new-checkout-flow', false)) {
  // Nouveau flow
  showNewCheckout();
} else {
  // Ancien flow
  showOldCheckout();
}

Bonnes pratiques

  • Pipeline as Code : Versionnez vos pipelines dans Git
  • Tests obligatoires : Bloquez les merges si les tests échouent
  • Builds rapides : Optimisez avec cache et parallélisation (max 10-15 min)
  • Fail fast : Exécutez les tests rapides en premier
  • Environnements isolés : Staging = copie exacte de production
  • Rollback automatique : Si le déploiement échoue, revenez à la version précédente
  • Monitoring : Surveillez les métriques après chaque déploiement
  • Blue-Green ou Canary : Minimisez l'impact des bugs en prod
  • Secrets sécurisés : Ne committez jamais de secrets dans Git
  • Notifications : Alertez l'équipe sur Slack en cas d'échec
  • Artifacts versionnés : Gardez les artefacts pour rollback rapide
  • Documentation : Documentez le processus de rollback manuel

Métriques à surveiller

Métrique Objectif
Build Time < 10 minutes
Deployment Frequency Plusieurs fois par jour
Lead Time < 1 heure (commit → production)
Mean Time to Recovery (MTTR) < 1 heure
Change Failure Rate < 15%
📊 DevOps Research and Assessment (DORA) : Ces métriques sont issues des recherches DORA et permettent de mesurer la maturité DevOps d'une équipe.

Conclusion

Les pipelines CI/CD sont devenus indispensables pour livrer des applications de qualité rapidement et en toute confiance. En automatisant build, tests et déploiement, vous réduisez les erreurs humaines et accélérez la mise en production.

Combinez CI/CD avec Docker, Kubernetes et Jenkins pour créer une chaîne DevOps complète et professionnelle.

📚 Pour aller plus loin :