Déploiement automatique avec GitLab CI - 03 - Écrire le .gitlab-ci.yml

Écrire un .gitlab-ci.yml simple et efficace. Un stage, un job, déploiement automatique sur push to main.

03 - Écrire le .gitlab-ci.yml

Ce que tu vas apprendre

  • La structure du .gitlab-ci.yml pour un déploiement automatique
  • Ce que fait chaque ligne du fichier
  • Les variables CI/CD et le groupe de concurrence
  • Quand utiliser un pipeline simple vs un pipeline multi-stages

Prerequisites


Le fichier complet

Voici le .gitlab-ci.yml qui tourne en production sur paltemps.fr. En entier :

yamlstages:
  - deploy

deploy-production:
  stage: deploy
  tags:
    - paltemps
  only:
    - main
  resource_group: production
  script:
    - cd $PROJECT_PATH
    - git pull origin main
    - docker compose build --no-cache
    - docker compose up -d
    - docker image prune -f

17 lignes. C'est tout. Pas de before_script de 40 lignes, pas de matrice de jobs, pas de cache artifacts. Un stage, un job, 5 commandes.

Ligne par ligne

stages: - deploy : on déclaré un seul stage. Dans un pipeline classique, tu aurais build, test, deploy. Ici, on n'a pas de tests automatises dans le pipeline (ils tournent en local), donc un seul stage suffit.

tags: - paltemps : ca dit a GitLab "exécuté ce job sur un runner qui a le tag paltemps". C'est le tag qu'on a donne au runner pendant l'enregistrement. Si tu as plusieurs runners (staging, production), les tags permettent de diriger les jobs vers le bon serveur.

only: - main : le job ne se lance que sur les pushes vers la branche main. Tu pushes sur une feature branch ? Rien ne se passe. Tu merges dans main ? Déploiement automatique. Simple et sécurisé.

resource_group: production : ca empeche deux déploiements de tourner en meme temps. Imagine que tu pushes deux commits a 10 secondes d'intervalle. Sans resource_group, les deux pipelines se lancent en parallèle, et tu te retrouves avec deux docker compose build simultanes. Le resource_group met en file d'attente : le deuxieme attend que le premier finisse.

cd $PROJECT_PATH : une variable CI/CD qu'on definit dans GitLab. Elle contient le chemin absolu vers le repo sur le VPS, genre /home/deploy/paltemps. On la met en variable plutot qu'en dur dans le YAML pour ne pas exposer la structure du serveur dans le repo.

git pull origin main : on récupéré les derniers changements. Le runner est sur le VPS, le repo est clone sur le VPS, donc c'est un pull local-to-remote classique.

docker compose build --no-cache : on reconstruit les images sans cache. Pourquoi --no-cache ? Parce qu'on s'est fait avoir (voir l'article 04). En résumé : le cache Docker peut servir des fichiers statiques obsolètes.

docker compose up -d : on relance les conteneurs en mode detache. Docker Compose est malin : il ne recree que les conteneurs dont l'image a change. Les autres continuent de tourner.

docker image prune -f : on supprime les images orphelines. Sans ca, chaque build accumule des images inutilisees et ton disque de 40 Go se remplit en 2 semaines.

Configurer la variable CI/CD

Va dans ton projet GitLab, puis Settings > CI/CD > Variables. Ajoute :

  • Key : PROJECT_PATH
  • Value : /home/deploy/paltemps (ou ton chemin)
  • Protected : oui (seulement accessible sur les branches protegees)
  • Masked : oui (pas affiche dans les logs)

Tu peux mettre d'autres variables ici : tokens d'API, mots de passe de base de donnees, clés secretes. Tout ce qui ne doit pas etre dans le repo Git.

Declencher un déploiement

Ca se fait tout seul sur chaque push vers main. Mais tu peux aussi déclencher manuellement un pipeline : va dans CI/CD > Pipelines > Run pipeline, choisis la branche main, et clique. Utile quand tu veux redeployer sans changer de code (par exemple apres un changement de variable d'environnement).

Pour vérifier le statut : CI/CD > Pipelines. Tu vois la liste de tous les pipelines avec leur statut (running, passed, failed). Clique sur un pipeline pour voir les logs du job en temps réel.

Quand un pipeline simple ne suffit plus

Notre pipeline a un stage et un job. Ca marche pour un projet ou :

  • Les tests tournent en local ou dans un pipeline séparé
  • Il n'y a qu'un environnement (production)
  • Le build est rapide (< 2 minutes)

Quand tu as besoin de plus, un pipeline multi-stages ressemble a ca :

yamlstages:
  - test
  - build
  - deploy

tests:
  stage: test
  tags:
    - paltemps
  script:
    - cd $PROJECT_PATH
    - bun test

build:
  stage: build
  tags:
    - paltemps
  script:
    - cd $PROJECT_PATH
    - docker compose build
  only:
    - main

deploy-production:
  stage: deploy
  tags:
    - paltemps
  only:
    - main
  resource_group: production
  script:
    - cd $PROJECT_PATH
    - docker compose up -d
    - docker image prune -f

Les tests tournent sur chaque push (toutes les branches). Le build et le deploy ne se font que sur main. Si les tests echouent, le deploy n'a pas lieu. C'est un bon modèle quand ton projet grandit et que tu veux un filet de sécurité.

Mais pour notre cas, le pipeline simple fait le job. Pas besoin de rajouter de la complexité juste pour le plaisir d'avoir un beau diagramme de pipeline.


Navigation : Precedent : 02 - Installer GitLab Runner | Suivant : 04 - Docker cache et rebuild


Sources

Retrouve d'autres articles techniques sur paltemps.fr.

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.