DĂ©couvrir la CI : Comment build mon SaaS en 3 minutes pour la prod ? 📩

· Lucas Videlaine


# 📚 Sommaire


# 1. Introduction : Une série CI/CD pour les devs pressés

Bienvenue dans cette sĂ©rie de deux articles dĂ©diĂ©e Ă  l’automatisation du cycle de vie d’un projet SaaS grĂące Ă  la CI/CD.

Que tu sois dĂ©veloppeur freelance, Ă©tudiant, ou en train de lancer ton propre SaaS, cette sĂ©rie te montrera comment automatiser rapidement — et proprement — ton processus de build et de dĂ©ploiement.

🎯 Objectif : à la fin de cet article, tu sauras comment :

  • builder automatiquement ton application,
  • puis la dĂ©ployer en production dĂšs que ton code est prĂȘt.

# đŸ§± Ce qu’on va faire ensemble

Dans ce premier article, on se concentre sur la CI — Continuous Integration — l’IntĂ©gration Continue :

🔧 Automatiser le build de ton application à chaque push de code.
✹ ​En bonus, on va mĂȘme voir comment scanner ton code source Ă  la recherche de vulnĂ©rabilitĂ©s !

Dans le prochain article, on abordera la CD — Continuous Deployment — le DĂ©ploiement Continu :

🚀 Envoyer automatiquement ton build en production, sans manip manuelle.


# 💡 Contexte du use-case — notre fil rouge

Imaginons, tu as développé un site vitrine avec React JS pour présenter ton futur service SaaS (ou tout autre webapp, mais prenons un exemple simple et concret !)
Tu veux maintenant que chaque modification du code que tu push sur ton repository Git :

  1. soit automatiquement scannée et buildée,
  2. soit prĂȘte Ă  ĂȘtre dĂ©ployĂ©e sans intervention manuelle.

Nous allons utiliser une stack simple et accessible :

  • GitLab pour hĂ©berger ton code et l'image du conteneur qui sera buildĂ©,
  • GitLab-CI pour automatiser le scan et la construction de l'iamge,
  • Docker pour packagĂ© et allĂ©ger au maximum ton build (tu n'es pas complĂ©tement Ă  l'aise avec Docker ? Pas de problĂšme : un article sur les commandes de base t'attend dĂ©jĂ ).

✅ Pas besoin d’infrastructure complexe ni de configuration obscure : on va droit au but.


🎯 RĂ©sultat Ă  la fin de cet article :
Un build automatisĂ© Ă  chaque commit, prĂȘt Ă  ĂȘtre dĂ©ployĂ© sereinement.


Parfait ! Voici la partie 2 – C’est quoi la CI ?, toujours au format Markdown, clair et pĂ©dagogique :


# 2. C’est quoi la CI ? (IntĂ©gration Continue)

L’IntĂ©gration Continue (ou Continuous Integration, CI) est une pratique clĂ© du DevOps moderne. Elle consiste Ă  automatiser l’exĂ©cution de tests, le build et la validation de ton code dĂšs qu’un changement est poussĂ© dans ton dĂ©pĂŽt Git.

Dit autrement :

đŸ› ïž Tu Ă©cris du code → tu pushes → ton projet est automatiquement construit et vĂ©rifiĂ©.


# ✅ Une dĂ©finition simple

CI = un script qui vĂ©rifie et construit ton code Ă  chaque commit, sans que tu aies besoin d’y penser.

Plus concrĂštement, une pipeline CI peut :

  • installer les dĂ©pendances de ton projet,
  • exĂ©cuter des tests unitaires ou de qualitĂ© de code,
  • compiler, builder ou packager ton app,
  • produire des fichiers prĂȘts pour la production (par ex. un dossier dist/ ou build/).

Aujourd'hui, Docker est largement employé dans les pipelines CI. Il permet à la pipeline de construire une image de conteneur, objet léger et simple à stocker pour les étapes suivantes du cycle vie logicielle (CD, etc.).


# đŸ€ La CI dans une dĂ©marche DevOps

La CI est l’un des premiers pas vers une dĂ©marche DevOps. Elle favorise :

  • la collaboration : tout le monde travaille sur une base de code testĂ©e et fonctionnelle,
  • la dĂ©tection rapide des erreurs : un bug dans la branche ? Tu le sais dĂšs le commit,
  • la rĂ©duction du temps de mise en production : pas besoin de tout refaire Ă  la main.

🔁 La CI Ă©limine les phases de “ça marche chez moi”, “je rebuild vite fait avant de pousser” et autres sources de friction.


# 💡 Pourquoi utiliser la CI pour mon SaaS ?

Tu pourrais penser : “Mais je suis seul sur ce projet, j’ai besoin de tout ça ?”
La réponse est : oui, surtout.

Voici pourquoi :

  • Tu gagnes du temps : pas besoin de rĂ©pĂ©ter manuellement les builds Ă  chaque changement.
  • Ton code est toujours prĂȘt pour la prod : pas de mauvaise surprise Ă  la derniĂšre minute.
  • Tu fiabilises ton projet : moins de risques d’introduire un bug ou de casser quelque chose.

💬 Astuce : Tu veux t’entraüner à la CI ? Notre projet React vitrine est un excellent terrain de jeu !


TrĂšs bien, voici la partie 3 – Outils utilisĂ©s pour notre pipeline, toujours en Markdown, avec un ton pĂ©dagogique et accessible :


# 3. Outils utilisés pour notre pipeline

Pour automatiser le build de notre site React, on va s’appuyer sur des outils modernes, simples Ă  prendre en main, et largement utilisĂ©s dans l’écosystĂšme Dev et DevOps.


# đŸ—‚ïž Git – La base de ton projet

Si tu lis cet article, tu utilises trĂšs probablement Git pour versionner ton code.
La CI va justement s’appuyer sur ton dĂ©pĂŽt Git pour savoir quoi builder, quand et comment.

Chaque fois que tu fais un commit et que tu le pushes, Git dĂ©clenche une nouvelle version du code Ă  analyser. C’est lĂ  que la magie de la CI entre en jeu.


# 🩊 GitLab – Le hub de ton projet

Dans cette série, nous allons utiliser GitLab, un service de gestion de code source qui inclut nativement un systÚme CI/CD intégré (contrairement à GitHub qui nécessite des actions externes, ou des outils comme GitHub Actions ou CircleCI).

✅ Pourquoi GitLab ?

  • Pas besoin d’installer ou connecter un outil externe,
  • La CI/CD est native, simple et efficace,
  • Tu peux hĂ©berger ton dĂ©pĂŽt en cloud (gitlab.com) ou on-premise (GitLab CE).

# 🔁 GitLab-CI – Le moteur du pipeline

GitLab-CI est le moteur qui exécute ton pipeline. Il lit un fichier de configuration .gitlab-ci.yml placé à la racine de ton projet, et déclenche automatiquement les étapes que tu y définis (scan, build, test, déploiement, etc.).

Ce fichier te permet de dire Ă  GitLab :

  • quelles Ă©tapes Ă  rĂ©aliser,
  • quelles commandes exĂ©cuter,
  • quoi garder comme rĂ©sultat (les artifacts),
  • dans quels cas exĂ©cuter chaque Ă©tape (branches, conditions, etc.).

📁 Un seul fichier .gitlab-ci.yml = toute la logique de ton pipeline.


# ⚠ PrĂ©requis : Ton projet doit ĂȘtre hĂ©bergĂ© sur GitLab.com

Pour suivre les exemples de cette série :

  • crĂ©e un compte gratuitement sur gitlab.com,
  • pousse ton dĂ©pĂŽt (React) sur un nouveau projet (public ou privĂ©, comme tu prĂ©fĂšres),
  • assure-toi que ton fichier .gitlab-ci.yml est bien Ă  la racine du dĂ©pĂŽt.

💬 Astuce : Tu peux tester ton fichier .gitlab-ci.yml dans l’UI GitLab avant mĂȘme de le pusher, via l’outil CI Lint.


# 4. Docker : l’alliĂ© discret de tout bon SaaS

Pour que ta pipeline CI fonctionne de maniĂšre fiable, reproductible, et indĂ©pendante de l’environnement de la machine qui l’exĂ©cute, on utilise Docker.

MĂȘme si ce n’est pas un article dĂ©diĂ© Ă  Docker, il est important de comprendre son rĂŽle dans la CI, car GitLab-CI repose fortement dessus.


# đŸ› ïž Quel rapport avec la CI ?

Dans un pipeline GitLab-CI, chaque job s’exĂ©cute dans un conteneur Docker.
Tu peux choisir l’image Docker Ă  utiliser pour ton projet en fonction de ta stack, mais dans notre cas nous allons utiliser une image gĂ©nĂ©rique afin de s'adapter Ă  tous les scĂ©narios possibles.

Pour cela, on utilise par exemple l’image docker permettant de faire du Docker-in-Docker "dind" :

image: docker:24.0.2-dind

Cela signifie : "GitLab, pour ce job, utilise telle image Docker dans telle version". Pour toutes les images et leurs versions (qu'on appelle "tag"), je t'invite Ă  te rendre sur Docker Hub.


# 📩 Le Dockerfile

Tu peux ensuite créer ton propre Dockerfile pour décrire les besoins de ton app.
Pour un projet React standard, voici une base que tu peux utiliser et ajuster selon tes envies :

Dockerfile :

# Dockerfile

FROM node:alpine3.22 AS build

WORKDIR /app

# Copy package files and install dependencies
COPY package*.json ./
RUN npm install

# Copy project files
COPY . .

# Build the application
RUN npm run build

# Production stage
FROM nginx:alpine

# Copy built assets from build stage
COPY --from=build /app/_site /usr/share/nginx/html

# Copy nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf

# Expose port 80
EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

Le fichier nginx.conf :

# nginx.conf
server {
listen 80;
server_name localhost;

root /usr/share/nginx/html;
index index.html;

# Gzip compression
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

# Security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

# Cache static assets
location /static/ {
expires 1y;
add_header Cache-Control "public, no-transform";
}
}

Pour tester ton Dockerfile, rien de plus simple :

docker build --tag 'mon-saas:1.0' ./Dockerfile
docker run --detach -p 8080:80 'mon-saas:1.0'
curl localhost:8080


# 💬 En rĂ©sumĂ©

Docker permet à GitLab CI de builder ton projet dans un environnement propre, contrÎlé et réutilisable.
Tu n’as rien Ă  installer sur ta machine : tout est exĂ©cutĂ© dans le cloud, Ă  chaque commit. Pour autant je t'encourage vivement Ă  l'utiliser aussi localement afin de tester ton app dans conteneur est assurer son fonctionnement agnostic !


# 5. Une pipeline CI "plug & play"

Maintenant que tu comprends les bases de la CI et le rĂŽle de Docker, passons Ă  la mise en pratique.
L’objectif : te fournir un pipeline clĂ© en main que tu peux coller dans ton dĂ©pĂŽt GitLab pour builder automatiquement ton SaaS Ă  chaque push.


# ⚙ Un fichier .gitlab-ci.yml simple et efficace

Voici un pipeline CI complet, prĂȘt Ă  l’emploi, intĂ©grant les bonnes pratiques DevSecOps dĂšs le dĂ©part, et qui s'adaptera Ă  tous tes projets :

# .gitlab-ci.yml

image: docker:29

services:
- name: docker:29-dind
entrypoint: ['env', '-u', 'DOCKER_HOST']
command: ['dockerd-entrypoint.sh']

variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2
REGISTRY: $CI_REGISTRY
REPOSITORY: $CI_PROJECT_NAMESPACE
IMAGE_NAME: $CI_PROJECT_NAME

include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/SAST-IaC.latest.gitlab-ci.yml
- template: Security/Secret-Detection.gitlab-ci.yml
- template: Jobs/Container-Scanning.gitlab-ci.yml

stages:
- test
- build
- scan

sast:
stage: test

build:
stage: build
before_script:
- echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
script:
- IMAGE_NAME="${IMAGE_NAME//./}"
- >
if [ "$CI_COMMIT_REF_NAME" = "main" ]; then
IMAGE_TAG="$CI_COMMIT_SHORT_SHA"
else
IMAGE_TAG="$CI_COMMIT_SHORT_SHA-dev"
fi

- docker build -t $REGISTRY/$REPOSITORY/$IMAGE_NAME:$IMAGE_TAG .
- docker push $REGISTRY/$REPOSITORY/$IMAGE_NAME:$IMAGE_TAG
after_script:
- docker logout $REGISTRY

container_scanning:
stage: scan
before_script:
- IMAGE_NAME="${IMAGE_NAME//./}"
- >
if [ "$CI_COMMIT_REF_NAME" = "main" ]; then
IMAGE_TAG="$CI_COMMIT_SHORT_SHA$"
else
IMAGE_TAG="$CI_COMMIT_SHORT_SHA-dev"
fi

- export CS_IMAGE="$REGISTRY/$REPOSITORY/$IMAGE_NAME:$IMAGE_TAG"

# 🧠 DĂ©chiffrons ce pipeline

ÉlĂ©mentRĂŽle
image: docker:29Utilise Docker pour permettre de builder et pousser une image de conteneur
services: docker:29-dindLance un démon Docker-in-Docker pour exécuter des builds dans le conteneur
variables:DĂ©clare les variables d’environnement liĂ©es au registre d’images GitLab
include:IntĂšgre des templates de sĂ©curitĂ© fournis par GitLab (SAST, IaC, secrets, scan d’image)
stages:Définit les étapes du pipeline : test, build, scan
sast:Active les tests SAST (analyse de code statique)
build:Build et push l’image Docker de ton projet
container_scanning:Lance une analyse de sĂ©curitĂ© sur l’image buildĂ©e

# 🔐 Ce pipeline fait bien plus que builder

Ce fichier .gitlab-ci.yml te donne un pipeline DevSecOps complet dÚs le départ :

  • 📩 Il build ton projet dans une image Docker
  • 🚀 Il push cette image dans le registre GitLab
  • đŸ›Ąïž Il scanne ton code source, tes secrets, ton infra-as-code et ton image Docker
  • 🔒 Il te signale toute vulnĂ©rabilitĂ© potentielle avant mĂȘme que tu dĂ©ploies

Pas besoin d’installer quoi que ce soit : GitLab fournit tous les outils intĂ©grĂ©s. Tu n’as qu’à pousser ton .gitlab-ci.yml.


# 🎯 RĂ©sultat

À chaque push :

  1. Ton code est scanné pour détecter des vulnérabilités ou fuites de secrets.
  2. Ton image Docker est construite et envoyée dans le registre GitLab.
  3. Ton image est scannĂ©e pour vĂ©rifier qu’elle est propre et sĂ»re.

✅ Ton build est propre, sĂ©curisĂ© et prĂȘt Ă  ĂȘtre dĂ©ployĂ© (spoiler : c’est pour le prochain article 😉).


# 6. Tester et adapter le pipeline

Tu as ton fichier .gitlab-ci.yml prĂȘt ? Parfait. Voyons oĂč le placer, comment lancer ton premier pipeline, et surtout comment vĂ©rifier que tout fonctionne correctement, Ă©tape par Ă©tape.


# 📁 OĂč placer les fichiers dans ton dĂ©pĂŽt ?

Voici une arborescence typique d’un projet React prĂȘt pour la CI :

mon-saas-vitrine/
├── public/
├── src/
├── .gitignore
├── Dockerfile
├── package.json
├── package-lock.json
├── README.md
├── .gitlab-ci.yml      👈 à la racine du projet

✅ Le fichier .gitlab-ci.yml doit ĂȘtre Ă  la racine du dĂ©pĂŽt GitLab pour ĂȘtre dĂ©tectĂ© automatiquement.

📩 N’oublie pas ton Dockerfile à la racine aussi, sinon ça ne fonctionnera pas !


# 🚀 Pousser ton code et dĂ©clencher le pipeline

Une fois ton projet sur GitLab :

git add .
git commit -m "Ajout du pipeline CI + Dockerfile"
git push origin main

GitLab va automatiquement détecter le fichier .gitlab-ci.yml et déclencher le pipeline.

Pipelines menu on GitLab repo

Pipeline result status

Pipeline result status

On peut confirmer ainsi que les 3 étapes de notre pipeline ont été réalisées avec succÚs !


# 🔍 VĂ©rifier l’exĂ©cution de chaque Ă©tape

# ✅ 1. Étape test (sast, secret-detection et IaC)

Ces étapes scannent :

  • Ton code source JS/TS pour dĂ©tecter les vulnĂ©rabilitĂ©s connues (XSS, injections, etc.)
  • Les fichiers versionnĂ©s pour repĂ©rer des secrets accidentellement committĂ©s (tokens, clĂ©s privĂ©es, etc.)
  • Les fichiers Infrastructure as Code (ex : Dockerfile)

Les rapports dĂ©taillĂ©s des scans sont visibles en tĂ©lĂ©chargeant les "artefacts" dans l’interface "Jobs" :

Pipeline jobs

⚠ Point d'attention ici, ce n'est pas parce que les Ă©tapes sont "Passed" que tout est OK pour autant !

â„č​​ Si tu prends le temps de tĂ©lĂ©charger et parcourir les rapports de vulnĂ©rabilitĂ©s, tu te rendras compte que tu peux largement amĂ©liorer la sĂ©curitĂ© de ton app.

❇​ Cette pipeline est dĂ©diĂ©e pour des SaaS au stade MVP, donc je n'ai pas souhaitĂ© la rendre trop bloquante, mĂȘme si des vulnĂ©rabilitĂ©s sont dĂ©tĂ©ctĂ©es, le build s'effectura.


# ✅ 2. Étape build

  • Cette Ă©tape build une image Docker avec ton application
  • Puis elle la push dans le registre de ton projet GitLab

Pipeline jobs

💬 Astuce : Si tu veux inspecter l’image, tu peux la pull en local :

docker login registry.gitlab.com
docker pull registry.gitlab.com/namespace/projet/image:latest

# ✅ 3. Étape container_scanning

  • Analyse l’image Docker gĂ©nĂ©rĂ©e : OS, librairies, dĂ©pendances
  • Rapporte les CVE critiques ou connues

MĂȘme mĂ©thode que pour le sast, secret-detection et IaC : dans Build/Jobs tu retrouveras le rapport de scan complet de l'image nouvellement construite. A toi de prendre le temps de la lire, de la comprendre, et de corriger ce que tu juges important pour ton SaaS !


# ⚠ Si le pipeline Ă©choue

đŸ§© GitLab t’indique clairement quelle Ă©tape a Ă©chouĂ©, et pourquoi.

  • Clique sur le nom du job concernĂ© dans l’UI du pipeline
  • Inspecte les logs complets pour corriger le problĂšme

💡 Astuce : Active les "failures notifications" dans les paramĂštres pour ĂȘtre alertĂ© par e-mail ou via intĂ©gration Slack.


# 7. Conclusion : ton build est prĂȘt !

FĂ©licitations ! 🎉 Tu viens de mettre en place un pipeline CI complet, sĂ©curisĂ© et automatisĂ© pour ton projet SaaS.
En quelques minutes, tu as posĂ© les bases d’un cycle de dĂ©veloppement professionnel, fiable et prĂȘt pour la production.


# ✅ Ce que tu as accompli

  • Compris les fondamentaux de la CI et son rĂŽle dans une dĂ©marche DevOps
  • UtilisĂ© GitLab-CI pour automatiser ton processus de build
  • IntĂ©grĂ© Docker pour fiabiliser ton environnement d’exĂ©cution
  • AjoutĂ© des scans de sĂ©curitĂ© (SAST, secrets, container scanning) sans effort
  • PrĂ©parĂ© ton projet pour le dĂ©ploiement continu

# 🚧 Ce qu’il reste Ă  faire ? Le dĂ©ploiement !

Ton build est prĂȘt, propre, versionné 
Il ne reste plus qu’à l’envoyer en production.

Et ça tombe bien : c’est l’objet du prochain article de cette sĂ©rie 👇


# 🔜 [À venir] Partie 2 – DĂ©couvrir la CD : Comment dĂ©ployer mon build en prod en 3 minutes ?

Tu y apprendras Ă  :

  • DĂ©ployer ton image Docker automatiquement sur un VPS
  • Mettre en place et configurer un modern reverse proxy
  • Automatiser les redĂ©ploiements avec Docker Compose

📌 En rĂ©sumĂ© : tu viens de franchir une Ă©tape clĂ© dans l’industrialisation de ton projet.
MĂȘme en solo, tu utilises les mĂȘmes outils que dans les grandes Ă©quipes.


Merci pour ta lecture 🙌
N’hĂ©site pas Ă  partager cet article ou me faire part de tes retours, idĂ©es d'amĂ©lioration ou suggestions d’articles !