1. Vue d’Ensemble

Un déploiement = make deploy APP=<cible> qui exécute ansible/playbooks/deploy.yml. Le playbook :

  1. Valide la cible (19 valeurs possibles, échec explicite sinon)

  2. Backup pre-deploy automatique des bases de données concernées (si leurs containers tournent)

  3. Git : clone le repo applicatif s’il est absent, sinon git clean -fd + pull (branche main par défaut)

  4. Docker : login au GitLab Registry → pull des images (si TAG) → docker compose up -d

  5. Vérifie que les containers tournent (pause 10–20s puis docker ps)

  6. Rollback automatique : en cas d’échec, relance le stack/service et échoue avec message clair

2. Les 19 Cibles de Déploiement

Stack ClaraJob (repo clarajob_sa, compose à la racine) :
  clarajob-sa            stack complet (git pull + pull 4 images + up -d tout)
  clarajob-ddl           PostgreSQL (git pull sous-repo + restart) [backup pre-deploy auto]
  clarajob-mongo         MongoDB (restart)                          [backup pre-deploy auto]
  clarajob-front-api     API Spring Boot (restart, image GitLab)
  clarajob-front-gui     Vue.js (git pull + npm build OU pull image + restart nginx)
  clarajob-embedding     FastAPI embedding (restart)
  clarajob-redis         Redis (restart)
  minio-service          MinIO S3 (restart)
  minio-backup           Sidecar backup MinIO mc mirror (restart)
  dozzle                 Dozzle logs (restart)

Stack PredictX (repo marketisia, compose docker/docker-compose.yml) :
  marketisia-sa          stack complet                              [backup pre-deploy auto]
  marketisia-front-api   API seule (restart)
  marketisia-front-gui   GUI seule (restart)

Auth (repo auth-server) :
  auth-server-db         PostgreSQL Keycloak (restart)              [backup pre-deploy auto]
  keycloak               Keycloak (restart)                         [backup DB pre-deploy auto]

Infra (repo sever-admin) :
  adminer                Adminer (restart)
  server-admin-doc       Nginx documentation sever-admin (restart)

Documentation projets (repo documentation) :
  documentation          Site AsciiDoc (git pull, build/ versionné + restart nginx)

Proxy (repo main-server-proxy) :
  traefik                Traefik (git pull + restart, TAG optionnel)

3. Paramètres

Paramètre Défaut Effet

TAG

latest

Passé comme IMAGE_TAG au compose et déclenche un docker compose pull du/des service(s). Sans TAG : pas de pull, redémarrage avec l’image déjà présente (sauf stacks complets qui pull toujours si le token registry est défini).

BRANCH

main (deploy_git_branch)

Branche Git pullée avant le déploiement

ENV

remote

remote → serveur production ; local → ta machine

make deploy APP=clarajob-sa                          # stack complet, images latest
make deploy APP=clarajob-sa TAG=v1.2.0               # version taguée
make deploy APP=clarajob-front-api TAG=abc1234       # commit SHA
make deploy APP=clarajob-ddl BRANCH=feature/my-branch
make deploy APP=clarajob-sa BRANCH=develop TAG=v1.2.0
make deploy APP=traefik TAG=v1.0.0
make deploy APP=documentation                        # pull (build/ versionné) + restart nginx
make deploy APP=clarajob-sa ENV=local

4. Déroulement Détaillé par Type

4.1. Type A — Stack complet (clarajob-sa, marketisia-sa)

Bloc inline dans deploy.yml avec rollback :

1. pre_tasks : backup pre-deploy des DBs du stack (si containers actifs)
     clarajob-sa    → backup clarajob-ddl (pg_dump) + clarajob-mongo (mongodump)
     marketisia-sa  → backup marketisia-ddl (pg_dump)
     (dumps marqués "pre-deploy" dans db-config/dump_description/)

2. Git (become_user: admin, clé /home/admin/.ssh/id_ed25519) :
     - clone si le répertoire n'existe pas
     - sinon : chown admin + git clean -fd + git pull --force (branche BRANCH|main)
     (ENV=local : pas de chown — deploy_fix_permissions=false — et pas de clean/pull
      si le repo existe — deploy_skip_pull_if_exists=true ; chemins locaux surchargés
      dans group_vars/local/vars.yml)

3. docker login registry.gitlab.com (deploy token vault — no_log)

4. Pull des images applicatives :
     clarajob-sa   → pull clarajob-ddl clarajob-front-api clarajob-front-gui clarajob-embedding
     marketisia-sa → pull marketisia-front-api marketisia-front-gui
     (compose marketisia : docker/docker-compose.yml)

5. IMAGE_TAG=<tag> docker compose up -d          (tout le stack)

6. Pause (15s clarajob / 20s marketisia) puis docker ps → affichage des containers

RESCUE (si n'importe quelle étape échoue) :
     docker compose up -d      ← relance le stack (rollback)
     fail "Déploiement échoué. Le stack a été relancé. Vérifier les logs."

4.2. Type B — Service individuel (rôle deploy)

Pour clarajob-ddl, clarajob-mongo, clarajob-front-api, clarajob-embedding, clarajob-redis, minio-service, minio-backup, dozzle, auth-server-db, keycloak, adminer, server-admin-doc, marketisia-front-api, marketisia-front-gui :

1. Validation des variables (app_name, app_service, project_dir, compose_dir)
2. Git clone/pull du repo parent (sauf si deploy_skip_pull_if_exists)
3. docker compose stop <service>
4. docker login (si token défini)
5. docker compose pull <service>        ← SEULEMENT si TAG fourni
6. IMAGE_TAG=<tag> docker compose up -d <service>
7. Pause 10s → docker ps → échec si le container n'apparaît pas
RESCUE : up -d (relance) + fail explicite

4.3. Type C — Frontend/site statique avec build (clarajob-front-gui, documentation — rôle deploy_frontend)

Le build est paramétrable via deux variables optionnelles du rôle :

  • build_image — image Docker du container de build (défaut : node_image, sinon node:lts-alpine)

  • build_command — commande exécutée dans le container (défaut : npm ci && npm run build)

Deux modes selon la présence de TAG :

SANS TAG (build sur le serveur) :
  git pull du repo parent
  docker compose stop <service>
  docker run --rm -v <project_dir>:/app -w /app <build_image> \
      sh -c "<build_command>"                ← build dans un container jetable
  docker compose up -d <service>             ← Nginx sert le nouveau contenu
  pause 15s + vérification

AVEC TAG (image pré-buildée par la CI) :
  git pull, stop, docker login, docker compose pull <service>,
  IMAGE_TAG=<tag> up -d, pause 15s + vérification

Cibles utilisant ce rôle :

Cible Build image Build command Contenu servi

clarajob-front-gui

node:lts-alpine

npm ci && npm run build (défauts)

clarajob-front-gui/dist/ monté par nginx

documentation n’utilise plus ce pattern : build/generatedSite est pré-généré en local (gradle asciidoctor) et versionné dans le repo — le déploiement passe par le rôle deploy simple (git pull + restart nginx, aucun build serveur, toujours sans TAG).

4.4. Type D — Traefik

git clone/pull main-server-proxy
Si TAG : TRAEFIK_IMAGE=registry.gitlab.com/app81724/proxy/main-server-proxy/traefik-service:<TAG>
         docker compose pull traefik-service
stop → up -d traefik-service → pause 10s → vérification → rollback si échec

Traefik est le point d’entrée HTTPS de tous les domaines. Pendant son restart (~10s), tous les sites sont brièvement indisponibles. À déployer en heures creuses.

5. Prérequis — Création des Images Docker (CI GitLab)

Le déploiement ne build jamais les images applicatives (sauf le mode « sans TAG » de clarajob-front-gui, Type C) : il les pull depuis le GitLab Container Registry. Avant tout déploiement, il faut donc s’assurer que les images existent, avec le bon tag.

Le build est automatisé par le .gitlab-ci.yml du repo clarajob_sa (Dockerfiles centralisés dans docker/). Un seul stage build, quatre jobs (docker-in-docker, login registry automatique via CI_REGISTRY_USER/CI_REGISTRY_PASSWORD — rien à configurer côté utilisateur) :

Job CI Image produite Déclencheur actif Tags poussés

build-api

<registry>/clarajob-front-api

push d’un tag (v*)

latest + SHA court

build-gui

<registry>/clarajob-front-gui

push d’un tag (v*)

latest + nom du tag

build-embedding

<registry>/clarajob-embedding

push d’un tag (v*)

latest + SHA court

build-pgvector

<registry>/clarajob-pgvector

push d’un tag (v*)

latest + SHA court

Chaque job pousse toujours deux tags : latest et ${CI_COMMIT_TAG} si le pipeline est déclenché par un tag Git, sinon ${CI_COMMIT_SHORT_SHA} (SHA court du commit).

La configuration actuelle est asymétrique : les déclencheurs develop, feature/* et tags sont commentés sur build-api/build-embedding/build-pgvector, et main est commenté sur build-gui. Conséquences :

  • Un tag v1.2.0 ne produit que clarajob-front-gui:v1.2.0. Un make deploy APP=clarajob-sa TAG=v1.2.0 échouera au pull des trois autres images (le tag n’existe pas pour elles).

  • Un push sur main ne rebuild pas la GUI (elle sera alors buildée sur le serveur en mode « sans TAG », voir Type C).

Pour un déploiement complet par version taguée, décommenter - tags dans les only: des quatre jobs (et pousser branche + tag : git push origin main --follow-tags).

5.1. Les possibilités pour produire les images

Option 1 — Déploiement latest (la plus simple, conf CI actuelle) :

# 1. Merger/pusher sur main → la CI build api, embedding, pgvector en :latest
git push origin main
# 2. Attendre le pipeline vert (GitLab → CI/CD → Pipelines)
# 3. Déployer sans TAG : la GUI est buildée sur le serveur (npm), le reste
#    redémarre sur l'image déjà présente ou pull latest (stack complet)
make deploy APP=clarajob-sa

Option 2 — Déploiement par version taguée (recommandé en production, nécessite - tags décommenté sur les 4 jobs) :

git tag v1.2.0                      # sur le commit à livrer (voir § Commandes utiles)
git push origin main --follow-tags  # déclenche le pipeline de tag
# → 4 images taguées v1.2.0 dans le registry
make deploy APP=clarajob-sa TAG=v1.2.0

Option 3 — Déploiement par SHA court (livrer un commit précis de main) :

git push origin main                # pipeline main → images :latest et :<sha-court>
git rev-parse --short HEAD          # ex: abc1234
make deploy APP=clarajob-front-api TAG=abc1234

Option 4 — Build manuel local (dépannage, CI indisponible) :

Nécessite un token GitLab avec le scope write_registry (deploy token ou PAT).

docker login registry.gitlab.com               # user + token write_registry
cd clarajob_sa
docker build -f docker/clarajob-front-api/Dockerfile \
  -t registry.gitlab.com/<groupe>/<projet>/clarajob-front-api:latest .
docker push registry.gitlab.com/<groupe>/<projet>/clarajob-front-api:latest
# idem pour clarajob-front-gui, clarajob-embedding ;
# pgvector se build depuis son propre contexte :
docker build -t registry.gitlab.com/<groupe>/<projet>/clarajob-pgvector:latest \
  docker/postgres-pgvector
docker push registry.gitlab.com/<groupe>/<projet>/clarajob-pgvector:latest

5.2. Vérifier que l’image existe avant de déployer

# Via l'UI GitLab : projet clarajob_sa → Deploy → Container Registry
# Ou en ligne de commande (nécessite docker login) :
docker manifest inspect \
  registry.gitlab.com/<groupe>/<projet>/clarajob-front-api:v1.2.0 > /dev/null \
  && echo "OK, le tag existe" || echo "ABSENT du registry"

6. Workflow Recommandé (pas à pas)

# 0. État des lieux
make ping                                        # connexion OK ?

# 1. Backup manuel de sécurité (en plus du pre-deploy auto)
make backup APP=clarajob-ddl
make backup APP=clarajob-mongo

# 2. Déploiement
make deploy APP=clarajob-sa TAG=v1.2.0

# 3. Vérification (le playbook affiche déjà les containers actifs)
ssh -i ~/.ssh/serverAdminSSHKeypair.pem admin@18.158.207.98
docker ps                                        # tous les containers Up ?
docker logs clarajob-front-api --tail 50         # pas d'erreurs au démarrage ?
exit

# 4. Vérification fonctionnelle via les UIs
#    Dozzle  (port 9999)  : logs temps réel
#    Beszel  (port 8090)  : CPU/RAM des containers
#    Grafana (port 3000)  : logs Loki centralisés

7. Revenir en Arrière (Rollback Manuel)

Il n’y a pas de commande make rollback. Deux mécanismes :

  1. Rollback automatique : intégré à chaque déploiement (rescue Ansible) — si le déploiement échoue, le service est relancé avec l’état précédent.

  2. Rollback manuel : redéployer une version antérieure connue :

# Revenir à la version précédente de l'API
make deploy APP=clarajob-front-api TAG=v1.1.9

# Si la DB a été corrompue par une migration : restaurer le dump pre-deploy
# (créé automatiquement juste avant le déploiement)
ssh -i ~/.ssh/serverAdminSSHKeypair.pem admin@18.158.207.98 \
  "ls -lht /home/admin/app/sever-admin/db-config/dump/clarajob-ddl/ | head -5"
make restore APP=clarajob-ddl DUMP=clarajob-ddl-2026-07-26_141502.sql

8. CI/CD Jenkins

Le Jenkinsfile du repo automatise backup + deploy :

Paramètres :
  TARGET_APP  : clarajob-sa | marketisia-sa   (choix)
  SKIP_BACKUP : false par défaut (déconseillé de le passer à true en production)

Stages :
  1. Checkout
  2. Backup pre-deploy  → ansible-playbook playbooks/backup.yml -e target_app=$TARGET_APP
  3. Deploy             → ansible-playbook playbooks/deploy.yml -e target_app=$TARGET_APP

Prérequis Jenkins :
  - Credential "Secret file" nommé VAULT_PASSWORD_FILE (contenu du .vault_password)
  - Ansible installé sur l'agent
  - Clé SSH du serveur dans le known_hosts de l'agent

Déclenchement : manuel ou webhook GitLab/GitHub.

9. Problèmes Courants

Symptôme Cause / Solution

Application 'xxx' inconnue

APP hors des 19 cibles — vérifier l’orthographe exacte (ex: clarajob-front-api, pas clarajob-api)

Le playbook échoue à l’étape Git

Clé /home/admin/.ssh/id_ed25519 absente du serveur ou pas enregistrée comme deploy key GitLab

docker login échoue

vault_gitlab_registry_token expiré/invalide dans vault.yml

Pull d’image échoue avec TAG

Le tag n’existe pas dans le registry — vérifier que la CI de l’appli a bien pushé l’image

« Le container X n’est pas en cours d’exécution après le redémarrage »

L’appli crashe au boot. Le rollback a déjà relancé l’ancien état. Voir docker logs <container> puis corriger (env manquante, DB inaccessible, port occupé)

Build npm échoue (clarajob-front-gui sans TAG)

Erreur de build front — voir la sortie Ansible ; alternative : passer par une image CI avec TAG=

Déploiement OK mais l’utilisateur voit l’ancienne version

Cache navigateur / cache Traefik — Ctrl+Shift+R ; vérifier que le bon container a redémarré (docker ps : colonne CREATED)

10. Checklist Avant Déploiement Production

□ make ping OK
□ Backup manuel des DBs concernées (make backup APP=...)
□ Les images existent dans le GitLab Registry avec le bon TAG (pipeline CI vert —
  voir « Prérequis — Création des Images Docker »)
□ Équipe prévenue (surtout pour clarajob-sa / marketisia-sa / traefik : restart complet)
□ Dozzle/Beszel ouverts pour surveiller pendant/après
□ Plan de repli connu : TAG précédent + nom du dump pre-deploy

11. Prochaines Étapes

12. Commandes utiles

lister les tag

# Lister tous les tags (simple)
git tag

# Lister les tags avec un motif
git tag -l "v1.*"

# Lister les tags avec plus de détails (commit SHA, date, message)
git tag -n1    # 1 ligne d'annotation
git tag -n5    # 5 lignes d'annotation

# Lister avec le commit associé
git tag -l --format='%(refname:short) %(objectname:short) %(creatordate:short)'

# Lister les tags triés par version (le plus récent en dernier)
git tag --sort=-version:refname

# Voir le tag le plus récent
git describe --tags --abbrev=0

# Voir tous les tags avec leur type (lightweight vs annotated)
git tag -l -n0 && git for-each-ref --sort=-version:refname --format='%(refname:short) %(objecttype)' refs/tags

Creer un tag

# Sur le commit actuel
git tag v1.0.0

# Sur un commit spécifique
git tag v1.0.0 abc1234

pusher les tag

# Pousser un seul tag
git push origin v1.0.0

# Pousser les commits ET les tags en une seule commande
git push origin --follow-tags

#Pousser une branche + ses tags
git push origin main --follow-tags

supprimer un tag

# Supprimer un tag local
git tag -d v1.0.0

# Ou avec --delete
git tag --delete v1.0.0

Workflow : supprimer localement + pousser

# 1. Supprimer localement
git tag -d v1.0.0

# 2. Pousser la suppression vers GitLab
git push origin --delete v1.0.0

le serveur doit avoir les variables d’environnement configurés, s’assurer que dans le .bashrc il y a l equivalent pour la prod de

set -a
while IFS= read -r f; do
  [ -f "$f" ] && source "$f"
done < <(find /media/multi2/projects/app/security/env -name '.env*.local' -type f 2>/dev/null | sort)
set +a