feat(deploy): ajoute un environnement dev déployé à la demande
Infra / Formatage et validation Terraform (push) Successful in 50s
Infra / Formatage et validation Terraform (push) Successful in 50s
Troisième projet Compose sur la VM ENI, /srv/enervision/dev, alimenté par workflow_dispatch de n'importe quelle branche autre que dev et main (https://dev.enervision.local:9443). La recette suit toujours dev, la production main. - deploy.yml : routage main -> prod, dev -> rec, autre -> dev ; groupe de concurrence par environnement et non plus par branche. - provision-host.sh : prépare le dossier dev (ports 9443, 5435, 8027, 8084) ; passe safe.directory à git, faute de quoi un second passage en root, celui de terraform apply, échoue sur les clones déjà remis au runner. - ADR 0017, 10-infra.md, 50-cicd.md, infra/README.md à jour.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
# 0017 - Un troisième environnement, `dev`, déployé à la demande depuis n'importe quelle branche
|
||||
|
||||
- Statut : accepté
|
||||
- Date : 2026-09-23
|
||||
|
||||
## Contexte
|
||||
|
||||
L'[ADR 0009](0009-deux-environnements-compose-sur-la-vm-eni.md) a posé deux environnements sur
|
||||
la VM ENI : la recette suit `dev`, la production suit `main`. Les environnements GitHub en
|
||||
comptent trois, `dev`, `rec` et `prod`, et le troisième ne déployait rien.
|
||||
|
||||
Il manque un endroit où montrer une branche de travail avant son merge : la recette ne doit
|
||||
porter que ce qui est intégré à `dev`, sinon elle cesse d'être une recette. Un
|
||||
`workflow_dispatch` sur une branche de travail envoyait d'ailleurs cette branche dans la
|
||||
recette, puisque tout ce qui n'était pas `main` y partait.
|
||||
|
||||
La VM est passée à 32 Go : une troisième TimescaleDB, réglée à 2 Go comme les deux autres,
|
||||
tient sans peine.
|
||||
|
||||
## Décision
|
||||
|
||||
**Un troisième projet Compose, `enervision-dev`, dans `/srv/enervision/dev`**, bâti exactement
|
||||
comme les deux autres : son clone, son `.env`, son certificat, préparés par
|
||||
`scripts/provision-host.sh`.
|
||||
|
||||
**Déployé à la demande, jamais sur un push.** `deploy.yml` envoie `main` en prod, `dev` en
|
||||
recette, et toute autre branche lancée depuis l'onglet Actions dans `dev`. Seul un membre ayant
|
||||
le droit d'écriture sur le dépôt peut lancer un workflow.
|
||||
|
||||
**Ports décalés d'un cran de plus** : HTTPS `9443`, et sur `127.0.0.1` la redirection HTTP
|
||||
`8083`, PostgreSQL `5435`, Mailpit `8027`, Airflow `8084`. Nom d'hôte `dev.enervision.local`,
|
||||
pour la même raison de cookie que la recette.
|
||||
|
||||
**Le groupe de concurrence suit l'environnement**, et non plus la branche : deux branches lancées
|
||||
coup sur coup écriraient sinon dans le même dossier en même temps.
|
||||
|
||||
## Alternatives écartées
|
||||
|
||||
- **`dev` suit la branche `dev` à chaque push, la recette devient manuelle** : la recette
|
||||
offrirait une version figée au jury, mais la doc CI/CD, l'ADR 0009 et l'habitude de l'équipe
|
||||
basculeraient à deux jours du rendu.
|
||||
- **Un environnement par branche de travail** : un projet Compose et une TimescaleDB par
|
||||
branche, sans mécanisme de nettoyage. La machine ne le porterait pas longtemps.
|
||||
- **Garder `dev` sur les postes seulement** : rien à montrer d'une branche non mergée sans
|
||||
passer par la recette.
|
||||
|
||||
## Conséquences
|
||||
|
||||
- Une branche de travail créée avant ce changement porte l'ancien `deploy.yml` : lancée à la
|
||||
main, elle part encore dans la recette. Limiter l'environnement GitHub `rec` à la branche
|
||||
`dev` ferme ce chemin, réglage que seul un administrateur du dépôt peut poser.
|
||||
- `dev` ne garde aucune donnée d'une branche à l'autre au-delà de ce que ses migrations
|
||||
acceptent : une branche dont les migrations divergent de `dev` peut laisser la base dans un
|
||||
état que la suivante refuse. Recréer le volume, `docker compose down -v`, est alors le remède.
|
||||
- Trois environnements construisent leurs images séparément : l'écart de l'ADR 0009, un même
|
||||
commit construit deux fois, reste ouvert jusqu'au passage à GHCR.
|
||||
@@ -227,26 +227,27 @@ Deux conséquences se propagent jusqu'à l'application, et elles ne se devinent
|
||||
- `APP_TRUST_PROXY_HEADERS` passe à vrai en même temps, sinon la limitation de débit par IP
|
||||
compte sur l'IP du proxy et devient globale.
|
||||
|
||||
### Deux environnements sur la même machine
|
||||
### Trois environnements sur la même machine
|
||||
|
||||
Statut : `En cours`, la machine n'étant pas encore provisionnée. Décision et motifs dans
|
||||
l'[ADR 0009](../adr/0009-deux-environnements-compose-sur-la-vm-eni.md).
|
||||
La VM `eadl-2025-nantes-g3` portera la recette et la production, chacune dans son clone du dépôt,
|
||||
son `.env` et son projet Compose. Le nom de projet préfixe volumes, réseau et conteneurs : rien
|
||||
n'est partagé. `scripts/provision-host.sh` prépare les deux dossiers, génère les secrets et les
|
||||
certificats, et ne démarre rien.
|
||||
Statut : `En cours`. Décision et motifs dans
|
||||
l'[ADR 0009](../adr/0009-deux-environnements-compose-sur-la-vm-eni.md), étendue à un troisième
|
||||
environnement par l'[ADR 0017](../adr/0017-environnement-dev-a-la-demande.md).
|
||||
La VM `eadl-2025-nantes-g3` porte le développement, la recette et la production, chacun dans son
|
||||
clone du dépôt, son `.env` et son projet Compose. Le nom de projet préfixe volumes, réseau et
|
||||
conteneurs : rien n'est partagé. `scripts/provision-host.sh` prépare les trois dossiers, génère
|
||||
les secrets et les certificats, et ne démarre rien.
|
||||
|
||||
| | Recette | Production |
|
||||
|---|---|---|
|
||||
| Branche, environnement GitHub | `dev`, `rec` | `main`, `prod` |
|
||||
| Dossier, projet Compose | `/srv/enervision/rec`, `enervision-rec` | `/srv/enervision/prod`, `enervision-prod` |
|
||||
| URL | `https://rec.enervision.local:8443` | `https://enervision.local` |
|
||||
| Proxy HTTP, HTTPS | `127.0.0.1:8081`, `8443` | `80`, `443` |
|
||||
| PostgreSQL, Mailpit, Airflow, sur `127.0.0.1` | `5434`, `8026`, `8082` | `5433`, `8025`, `8080` |
|
||||
| | Développement | Recette | Production |
|
||||
|---|---|---|---|
|
||||
| Branche, environnement GitHub | toute branche lancée à la main, `dev` | `dev`, `rec` | `main`, `prod` |
|
||||
| Dossier, projet Compose | `/srv/enervision/dev`, `enervision-dev` | `/srv/enervision/rec`, `enervision-rec` | `/srv/enervision/prod`, `enervision-prod` |
|
||||
| URL | `https://dev.enervision.local:9443` | `https://rec.enervision.local:8443` | `https://enervision.local` |
|
||||
| Proxy HTTP, HTTPS | `127.0.0.1:8083`, `9443` | `127.0.0.1:8081`, `8443` | `80`, `443` |
|
||||
| PostgreSQL, Mailpit, Airflow, sur `127.0.0.1` | `5435`, `8027`, `8084` | `5434`, `8026`, `8082` | `5433`, `8025`, `8080` |
|
||||
|
||||
Les deux noms d'hôte visent la même IP, à déclarer dans le `/etc/hosts` des postes. Deux noms
|
||||
Les trois noms d'hôte visent la même IP, à déclarer dans le `/etc/hosts` des postes. Deux noms
|
||||
distincts sont nécessaires : le cookie `__Secure-ev_refresh` est posé par hôte, pas par port.
|
||||
La redirection HTTP de la recette est ramenée sur la boucle locale parce que la configuration
|
||||
La redirection HTTP de la recette et du développement est ramenée sur la boucle locale parce que la configuration
|
||||
Nginx renvoie vers `https://$host` sans port, c'est-à-dire vers la production.
|
||||
|
||||
Le déploiement est décrit dans [50-cicd.md](50-cicd.md) : un runner GitHub Actions installé sur
|
||||
@@ -267,7 +268,7 @@ sequenceDiagram
|
||||
|
||||
TF->>VM: SSH, get.docker.com puis docker compose version
|
||||
TF->>VM: copie et exécute scripts/provision-host.sh
|
||||
VM->>VM: deux clones, deux .env, deux certificats
|
||||
VM->>VM: trois clones, trois .env, trois certificats
|
||||
TF->>VM: installe actions-runner, config.sh, svc.sh
|
||||
VM->>GH: le runner s'enregistre avec le label eni-g3
|
||||
```
|
||||
|
||||
@@ -131,13 +131,14 @@ entrant n'est ouvert.
|
||||
|---|---|---|---|
|
||||
| `push` sur `dev` | `rec` | `/srv/enervision/rec` | aucune : la recette suit `dev` |
|
||||
| `push` sur `main` | `prod` | `/srv/enervision/prod` | approbation d'un relecteur dans l'environnement `prod`, branche `main` seule autorisée |
|
||||
| `workflow_dispatch` sur toute autre branche | `dev` | `/srv/enervision/dev` | droit d'écriture sur le dépôt, seul à pouvoir lancer un workflow ([ADR 0017](../adr/0017-environnement-dev-a-la-demande.md)) |
|
||||
|
||||
Le job aligne le clone sur la branche (`fetch`, `checkout`, `reset --hard`), lance
|
||||
`make stack-up`, qui reconstruit les images, redémarre les conteneurs puis applique les
|
||||
migrations Alembic dans le conteneur backend, et attend jusqu'à trois minutes que
|
||||
`/api/v1/health/ready` réponde derrière le proxy. Cette sonde ne vérifie que la connexion à la
|
||||
base et la présence de TimescaleDB : sans la migration, le déploiement serait vert sur une base
|
||||
sans schéma, et c'est pourquoi `make stack-up` la porte. Un groupe de concurrence par branche,
|
||||
sans schéma, et c'est pourquoi `make stack-up` la porte. Un groupe de concurrence par environnement,
|
||||
sans annulation, empêche deux déploiements simultanés du même environnement.
|
||||
|
||||
Le job ne fait pas de `actions/checkout` dans son espace de travail, et c'est voulu : le dossier
|
||||
@@ -157,7 +158,7 @@ passé à `scripts/provision-host.sh` fixe ce propriétaire.
|
||||
|
||||
La machine se prépare avec `scripts/provision-host.sh`, qui vérifie Docker et Compose 2.24.4 ou
|
||||
plus, clone les deux branches, génère les secrets de chaque `.env` et les certificats
|
||||
auto-signés, et ne démarre rien. Le détail des deux environnements, ports et noms d'hôte, est
|
||||
auto-signés, et ne démarre rien. Le détail des trois environnements, ports et noms d'hôte, est
|
||||
dans [10-infra.md](10-infra.md).
|
||||
|
||||
## Ce qui bloque un merge
|
||||
|
||||
Reference in New Issue
Block a user