Aller au contenu

Environnements & CI/CD — DYNORS

Nomenclature (ADR-0016 / ADR-0019)

Cible : LOCAL → DEV → INT → RMOA → PROD. Les libellés RMOA DYNORS / RMOA CLIENT et les fichiers sirrat.config.yml dans le repo app sont legacy — voir SIRRAT — concept et Structure Git.

Guide pratique pour mettre en place une plateforme DevOps reproduisant la chaîne locale → dev → int → rmoa → prod.


Principe : environnements et pipeline (cible)

Local  ──►  DEV  ──►  INT  ──►  RMOA  ──►  PROD
  (dev)   (auto CI)  (qualif)   (métier)   (CTO + PV)

En local : docker-compose.local.yml + .env.local uniquement. Hors local, URLs et secrets sont injectés par SIRRAT Forge — pas de .env.dev / .env.prod versionnés dans le repo app.


Stack CI/CD gratuite recommandée

DYNORS utilise déjà GitLab (gitlab.com). La solution la plus simple et gratuite est d'utiliser GitLab CI + runners auto-hébergés sur un petit VPS.

Composant Outil Coût Pourquoi
Code + pipeline GitLab CI Gratuit (gitlab.com) Déjà utilisé
Runners CI GitLab Runner self-hosted Gratuit (VPS 10–15 €/mois) Contrôle total
Registry Docker GitLab Container Registry Gratuit Intégré à GitLab
Secrets / variables GitLab CI/CD Variables Gratuit Protégées, masquées
Notifications Slack (plan gratuit) Gratuit Webhooks CI
Monitoring Grafana + Prometheus Gratuit (self-hosted) Stack standard
Logs Loki + Grafana Gratuit (self-hosted) Intégré à Grafana

Alternative si pas de GitLab : Woodpecker CI — open source, Docker-based, compatible GitHub/Gitea/Forgejo.


Installation d'un runner GitLab self-hosted

# Sur un VPS Ubuntu/Debian
# 1. Installer Docker
curl -fsSL https://get.docker.com | sh

# 2. Installer GitLab Runner
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get install gitlab-runner

# 3. Enregistrer le runner (token depuis GitLab → Settings → CI/CD → Runners)
sudo gitlab-runner register \
  --url https://gitlab.com/ \
  --registration-token YOUR_TOKEN \
  --executor docker \
  --docker-image "docker:latest" \
  --description "dynors-runner-prod" \
  --tag-list "dynors-runner" \
  --docker-privileged

Un runner peut servir tous vos projets GitLab.


Structure des fichiers par projet

dynors-projects/clients/mon-projet/
├── .gitlab-ci.yml                   # Pipeline CI/CD
├── docker-compose.local.yml         # Stack locale (dev machine) — seul compose app obligatoire
├── .env.example                     # Template (commité, sans secrets)
├── .env.local                       # LOCAL (gitignored, SIRRAT_ENABLED=false)
├── backend/
│   └── src/main/resources/
│       ├── application.yml                  # Config commune (placeholders)
│       └── application-local.yml            # Profil local

Legacy — ne plus ajouter

  • sirrat.config.ymlSIRRAT Forge
  • docker-compose.dev.yml + .env.dev → déploiement injecté par SIRRAT
  • application-rmoa-*.yml → profils gérés plateforme
Archive — arborescence historique multi-env (lecture seule)
└── scripts/
    ├── deploy-dev.sh
    ├── deploy-rmoa-dynors.sh
    ├── deploy-rmoa-client.sh
    ├── deploy-prod.sh
    ├── backup-prod.sh
    └── rollback.sh

Template docker-compose.local.yml (seul compose app)

services:
  backend:
    build: ./backend
    env_file: .env.local
    ports:
      - "8080:8080"
    depends_on:
      - postgres
      - redis

  postgres:
    image: postgres:15
    environment:
      POSTGRES_DB: ${DB_NAME:-app_local}
      POSTGRES_USER: ${DB_USER:-app}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-local}
    volumes:
      - postgres_local_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine

volumes:
  postgres_local_data:

Hors local, le déploiement (images, env, URLs couloir SLY) est piloté par SIRRAT — pas de docker-compose.dev.yml dans le repo app.

Archive — template `docker-compose.dev.yml` (legacy, ne plus ajouter)
version: "3.8"
services:
  backend:
    image: ${CI_REGISTRY_IMAGE}/backend:dev-${CI_COMMIT_SHORT_SHA}
    env_file: .env.dev
    ports:
      - "8080:8080"
    depends_on:
      - postgres
      - redis
  # … frontend, postgres, redis — voir historique Git si besoin

Template .env.example (local uniquement)

# ─── Local dev uniquement ───────────────────────────────
# Hors local : secrets et URLs injectés par SIRRAT Forge + Vault (ESO)

SIRRAT_ENABLED=false

LOG_LEVEL=DEBUG

# SLY local (gateway)
SLY_BASE_URL=http://localhost:8090
SLY_FORWARD_SECRET=local-sly-secret

DB_HOST=localhost
DB_PORT=5432
DB_NAME=
DB_USER=
DB_PASSWORD=

# Mocks dev
PAYMENT_PROVIDER=mock
EMAIL_PROVIDER=mock
STORAGE_PROVIDER=filesystem

Interdit dans le repo app

Pas de .env.dev, .env.rmoa-*, .env.prod versionnés. Pas de SIRRAT_API_TOKEN côté app — injecté par la CI/plateforme au déploiement.

Archive — `.env.example` multi-env (legacy)
ENVIRONMENT=               # local | dev | rmoa-dynors | rmoa-client | prod  ← déprécié
SIRRAT_ENABLED=
SIRRAT_API_URL=
SIRRAT_PROJECT_ID=
SIRRAT_API_TOKEN=          # jamais dans Git
# … voir historique

Pipeline GitLab CI — structure (cible)

Stages typiques alignés ADR-0016 :

stages:
  - build
  - test
  - publish
  - notify-sirrat
  # deploy-* : déclenchés par SIRRAT / manuel selon env (DEV auto, INT/RMOA/PROD manuel)

Extrait minimal (Java 21, notify SIRRAT après publish) :

variables:
  GRADLE_OPTS: "-Dorg.gradle.daemon=false"
  SIRRAT_API_URL: "https://sirrat.dynors.com/api"

build:backend:
  stage: build
  image: eclipse-temurin:21-jdk
  script:
    - cd backend && ./gradlew clean bootJar -x test
  artifacts:
    paths: [backend/build/libs/*.jar]
  tags: [dynors-runner]

test:unit:
  stage: test
  image: eclipse-temurin:21-jdk
  services: [postgres:15, redis:7]
  script:
    - cd backend && ./gradlew test jacocoTestReport
  tags: [dynors-runner]

notify:sirrat:
  stage: notify-sirrat
  script:
    - |
      curl -sf -X POST "$SIRRAT_API_URL/projects/$SIRRAT_PROJECT_ID/artifact-ready" \
        -H "Authorization: Bearer $SIRRAT_API_TOKEN" \
        -H "Content-Type: application/json" \
        -d "{\"environment\":\"dev\",\"version\":\"$CI_COMMIT_SHORT_SHA\"}" \
        || echo "SIRRAT notify skipped"
  allow_failure: true
  only: [develop, main]
  tags: [dynors-runner]

Voir GitLab — intégration CI / notify SIRRAT.

Archive — pipeline complet RMOA DYNORS/CLIENT (legacy) Anciens stages `deploy-rmoa-dynors`, `deploy-rmoa-client`, SSH + `docker-compose.dev.yml`, URLs `dev-$CI_PROJECT_NAME.dynors.com`, image `gradle:8.5-jdk17` — **dépréciés** (ADR-0018 : hors-prod via SLY couloir `sly-{env}-{lane}.hp.intranet.dynors.com/{app}/…`).
# Extrait historique — ne pas copier tel quel
stages: [build, test, deploy-dev, deploy-rmoa-dynors, deploy-rmoa-client, deploy-prod]
deploy:rmoa-dynors: { stage: deploy-rmoa-dynors, when: manual }
deploy:rmoa-client: { stage: deploy-rmoa-client, when: manual }

Variables CI/CD GitLab à configurer

Dans GitLab → Settings → CI/CD → Variables (protégées + masquées) :

# SIRRAT (notify CI — pas dans le repo app)
SIRRAT_API_TOKEN
SIRRAT_PROJECT_ID

# Registry / build
GITLAB_TOKEN              # Package Registry com.dynors.*
CI_REGISTRY_USER
CI_REGISTRY_PASSWORD

# Runners uniquement si besoin de smoke tests inter-app
SLY_FORWARD_SECRET        # injecté aussi par SIRRAT au déploiement — Vault en prod

# Notifications
SLACK_WEBHOOK

Secrets applicatifs (DB, JWT, PSP) : Vault → ESO → env au déploiement — pas de DB_RMOA_*_PASSWORD dupliqués dans GitLab « par confort ». Voir Vault — stratégie.


INT & RMOA — alignement pré-prod / prod

Objectif : INT (qualif technique) et RMOA (validation métier) aussi proches que possible de PROD :

Aspect INT / RMOA PROD Comment aligner
Base de données PostgreSQL 15 PostgreSQL 15 ✅ même version
SSL Requis Requis ✅ même config
Storage MinIO (compatible S3) S3 ou MinIO ✅ même API
Paiements Sandbox / mock Production ⚠ Tester les cas limites avant PROD
SLY (hors-prod) sly-{env}-{lane}.hp.intranet.dynors.com/{app}/… Domaines marque propres ADR-0018
SLY (inter-app Bus) actif actif même stack
SLY_FORWARD_SECRET Vault cercle Vault prod ✅ policies moindre privilège
Redis Oui Oui
Sentry Activé (env int/rmoa) Activé (prod) projets séparés

Branches Git (GitFlow adapté DYNORS)

main                          # 😇 PRODUCTION
develop                       # 🔥 DEV (CI + notify SIRRAT)
release/v1.3.0                # 🌫 INT puis RMOA (gates SIRRAT)
feature/nom-feature           # 😈 En dev
hotfix/correctif-critique     # 🚨 Urgence prod

Legacy

Branches release/v1.3.0-internal (RMOA DYNORS) et distinction RMOA CLIENT — remplacées par INT + RMOA avec attributs SIRRAT (acceptance, operated_by — ADR-0019).

Protections GitLab (Settings → Repository → Protected branches) :

main:
  push: No one
  merge: Maintainers
  force_push: false

develop:
  push: Developers + Maintainers
  merge: Developers + Maintainers

release/*:
  push: Maintainers only
  merge: Maintainers only

Checklist nouveau projet

☐ 1. Créer le repo GitLab dans dynors-projects/
☐ 2. Copier template .gitlab-ci.yml + adapter les stages
☐ 3. Déclarer l'app dans **SIRRAT Forge** (pas de `sirrat.config.yml` dans le repo)
☐ 4. Créer **`docker-compose.local.yml`** + **`.env.local`** (SIRRAT_ENABLED=false)
☐ 5. Créer **`.env.example`** (template local, sans secrets)
☐ 6. Configurer les branches protégées GitLab
☐ 7. Ajouter les variables CI/CD GitLab (cf. liste § 4)
☐ 8. Déclarer le projet dans SIRRAT
☐ 9. Configurer les canaux Slack (#dev-X, #qa-X, #prod-alerts)
☐ 10. Premier push → vérifier pipeline **build + test + notify SIRRAT**