Mise en place d’une chaîne CI/CD complète avec GitLab CI pour un déploiement continu Full Stack
La création d’une chaîne CI/CD robuste dans GitLab CI permet de fiabiliser la livraison logicielle et de réduire les écarts entre environnements. Un parcours Full Stack (front-end, back-end, tests, build, déploiement) gagne en consistance lorsque chaque étape est automatisée, versionnée et traçable.
Objectifs d’une CI/CD Full Stack
Standardisation
La pipeline doit exécuter des tâches identiques à chaque commit : compilation, lint, tests unitaires, tests d’intégration, packaging et déploiement.
Qualité et sécurité
Les contrôles automatisés (tests, analyse statique, gestion des secrets) garantissent un niveau de qualité constant. L’usage d’outils de scanning peut aussi limiter l’exposition aux vulnérabilités.
Déploiement continu
Les environnements staging et production doivent être alimentés à partir d’artefacts “reproductibles”. L’exécution conditionnelle selon les branches et tags est essentielle.
Architecture recommandée
Une architecture typique sépare clairement les responsabilités :
- Frontend : build web (ex. Angular/React/Vue) et publication d’artefact statique
- Backend : build API (ex. Node.js/Java/.NET) et génération d’image conteneur
- Tests : unitaires, e2e (côté front) et éventuellement tests d’intégration back-end
- Déploiement : provisionnement/rollout via scripts ou infrastructure as code
Pré-requis
Registre d’images et authentification
GitLab CI peut pousser des images vers un registre (GitLab Container Registry, Harbor, Docker Hub). Les identifiants sont fournis via Variables CI/CD.
Environnements
Au minimum :
- staging (pour valider avant production)
- production (déploiement contrôlé, idéalement déclenché sur tag)
Configuration GitLab CI : principes
La configuration s’appuie sur :
- Stages : lint/test/build/deploy
- Artifacts : livrer les résultats de build entre jobs
- Cache : accélérer l’exécution (dépendances, node_modules, etc.)
- Règles : lancer certains jobs seulement sur branches ou tags
Exemple de pipeline .gitlab-ci.yml (scénario Full Stack)
Le fragment ci-dessous illustre une chaîne classique : installation front/back, tests, build, packaging et déploiement.
Variables et cache
<!-- .gitlab-ci.yml -->
stages:
- lint
- test
- build
- package
- deploy
variables:
NODE_ENV: "production"
DOCKER_IMAGE: "$CI_REGISTRY_IMAGE"
# Exemple : réglage TLS/SSL si nécessaire
# DOCKER_TLS_CERTDIR: "/certs"
cache:
key: "${CI_COMMIT_REF_SLUG}"
paths:
- frontend/node_modules/
- backend/node_modules/
Job Frontend : lint et tests
lint_frontend:
stage: lint
image: node:20-alpine
script:
- cd frontend
- npm ci
- npm run lint
rules:
- changes:
- frontend/**/*
- package-lock.json
- frontend/package*.json
test_frontend:
stage: test
image: node:20-alpine
script:
- cd frontend
- npm ci
- npm run test -- --runInBand
artifacts:
when: always
reports:
junit: frontend/junit.xml
rules:
- changes:
- frontend/**/*
- frontend/package*.json
Job Backend : tests et analyse
test_backend:
stage: test
image: node:20-alpine
script:
- cd backend
- npm ci
- npm run test
artifacts:
when: always
reports:
junit: backend/junit.xml
rules:
- changes:
- backend/**/*
- backend/package*.json
Build Frontend : artefact statique
build_frontend:
stage: build
image: node:20-alpine
script:
- cd frontend
- npm ci
- npm run build
artifacts:
expire_in: 1 week
paths:
- frontend/dist/
rules:
- if: '$CI_COMMIT_BRANCH'
changes:
- frontend/**/*
Build Backend : image conteneur
Pour un déploiement cohérent, l’API est empaquetée en image Docker. Un job utilise le mode Docker-in-Docker ou un builder adapté.
build_backend_image:
stage: package
image: docker:27
services:
- name: docker:27-dind
command: ["--tls=false"]
variables:
DOCKER_HOST: "tcp://docker:2375"
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
script:
- docker build -t "$DOCKER_IMAGE:$CI_COMMIT_SHA" ./backend
- docker push "$DOCKER_IMAGE:$CI_COMMIT_SHA"
rules:
- if: '$CI_COMMIT_BRANCH'
changes:
- backend/**/*
Déploiement Staging
Le déploiement peut combiner l’artefact front et l’image back. L’exemple ci-dessous suppose l’usage d’un script (ou helm/kustomize) qui exécute les mises à jour côté infrastructure.
deploy_staging:
stage: deploy
image: alpine:3.20
needs:
- job: build_frontend
artifacts: true
- job: build_backend_image
environment:
name: staging
url: https://staging.example.com
script:
- echo "Déploiement sur staging..."
- ls -la frontend/dist
- export FRONT_ARTIFACT="frontend/dist"
- export BACK_IMAGE="$DOCKER_IMAGE:$CI_COMMIT_SHA"
- sh ./deploy/deploy_staging.sh
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
Déploiement Production (sur tag)
deploy_production:
stage: deploy
image: alpine:3.20
needs:
- job: build_frontend
artifacts: true
- job: build_backend_image
environment:
name: production
url: https://example.com
script:
- echo "Déploiement sur production..."
- export FRONT_ARTIFACT="frontend/dist"
- export BACK_IMAGE="$DOCKER_IMAGE:$CI_COMMIT_SHA"
- sh ./deploy/deploy_production.sh
rules:
- if: '$CI_COMMIT_TAG'
when: manual
Bonnes pratiques pour une CI/CD durable
1) Déployer à partir d’artefacts immuables
Les artefacts et images devraient être associés à un identifiant fixe (commit SHA ou tag). Cela améliore la traçabilité et facilite le rollback.
2) Séparer build et deploy
Les jobs de build préparent des sorties standard (dist, images). Les jobs de déploiement ne font ensuite que consommer ces sorties.
3) Contrôler les déclencheurs
Les rules doivent minimiser les exécutions inutiles et protéger la production. Un déploiement sur tag (avec approbation manuelle) réduit les risques.
4) Gérer la sécurité des secrets
Les variables sensibles doivent être stockées dans GitLab CI/CD. Les scripts de déploiement ne doivent jamais inclure de secrets en dur.
5) Ajouter des observabilités
La pipeline peut publier des logs et métadonnées. L’intégration à un système de monitoring (alerting, tracing) aide à détecter les régressions post-déploiement.
Déploiement : options courantes
- Kubernetes (Helm/Kustomize) : idéal pour orchestrer front/back et gérer les rollouts
- VM + scripts : simple au départ, mais nécessite une discipline de versionnement
- Serverless : utile pour certaines parties (API, fonctions), avec des artefacts packagés
Évolutions possibles
Approche “test en parallèle”
Les jobs front et back peuvent être parallélisés via un découpage fin des stages. Cela réduit le temps total de pipeline.
Gate de qualité
Un job “quality gate” peut consolider les résultats (lint, couverture de code, scans) et refuser la promotion vers staging/production.
Rollback automatisé
En cas de détection de régression (health checks), un rollback peut être déclenché sur la version précédemment validée.
Conclusion
Une CI/CD complète avec GitLab CI pour un déploiement continu Full Stack se construit autour d’une idée centrale : standardiser les étapes, rendre les sorties immuables et contrôler strictement les promotions. Avec une pipeline bien structurée, les livraisons deviennent plus fréquentes, plus sûres et plus faciles à auditer.
À propos de l'auteur
Laty Gueye Samba est développeur Full Stack basé à Dakar, Sénégal. Spécialiste des écosystèmes Java / Spring Boot et Angular.
Contact : latygueyesamba@gmail.com | Dakar, Sénégal