docs : spec phase 2a deploiement de version et versions disponibles

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 15:12:17 +02:00
parent e6aec7d95a
commit db71cc92ee

View File

@@ -0,0 +1,155 @@
# Phase 2a — Deploiement de version + Versions disponibles
## Contexte
Central gere les applications du SI Malio. La phase 1 a mis en place le CRUD des applications et environnements en BDD. Cette phase ajoute la capacite de deployer une version sur un environnement et de lister les versions disponibles sur le registry Gitea.
Chaque app a un `deploy.sh` qui prend un tag en argument, pull l'image Docker, lance les migrations, et gere le mode maintenance. Le script tourne sur la machine host. Central tourne en Docker et accede au host via le socket Docker monte.
## Architecture
### Variable d'environnement
`GITEA_API_TOKEN` : token global Gitea avec acces lecture aux packages. Configure dans `.env` (backend Symfony). Non stocke en BDD.
`GITEA_API_URL` : URL de base de l'API Gitea (ex: `https://gitea.malio.fr`). Configure dans `.env`.
### Service GiteaRegistryService
Classe PHP dans `src/Service/GiteaRegistryService.php`.
Responsabilite : appeler l'API Gitea pour lister les tags d'une image container.
API Gitea : `GET {GITEA_API_URL}/api/v1/packages/{owner}/container/{package}` avec header `Authorization: token {GITEA_API_TOKEN}`.
- Input : `registryImage` de l'Application (ex: `gitea.malio.fr/malio-dev/sirh`) — on extrait `owner` (`malio-dev`) et `package` (`sirh`) depuis cette string.
- Output : liste de tags tries par date de creation (plus recent en premier), chaque tag avec son nom et sa date.
- Gestion d'erreur : si l'API est inaccessible ou le token invalide, renvoyer une erreur claire.
### Service DeployService
Classe PHP dans `src/Service/DeployService.php`.
Responsabilite : executer le script de deploy d'un environnement.
- Input : entite `Environment` + tag a deployer
- Execute `deployScriptPath` avec le tag en argument via `Symfony\Component\Process\Process`
- Timeout : 300 secondes (5 min max pour un deploy)
- Capture stdout + stderr
- Output : objet avec `success` (bool), `output` (string), `exitCode` (int)
Le process tourne dans le container Central. Le `deploy.sh` est accessible car les dossiers des apps sont montes dans le container. Le script utilise `docker compose` qui fonctionne grace au socket Docker monte.
### Endpoints API
| Route | Methode | Description | Securite |
|-------|---------|-------------|----------|
| `GET /api/applications/{slug}/tags` | GET | Liste les tags disponibles sur le registry Gitea | ROLE_ADMIN |
| `POST /api/environments/{id}/deploy` | POST | Lance un deploy, body: `{ "tag": "v1.2.3" }` | ROLE_ADMIN |
#### GET /api/applications/{slug}/tags
Provider custom `TagListProvider` dans `src/State/`.
- Charge l'Application par slug
- Appelle `GiteaRegistryService` avec le `registryImage`
- Retourne la liste des tags
Response :
```json
{
"tags": [
{ "name": "v1.2.3", "date": "2026-04-05T10:00:00Z" },
{ "name": "v1.2.2", "date": "2026-04-01T08:00:00Z" },
{ "name": "latest", "date": "2026-04-05T10:00:00Z" }
]
}
```
#### POST /api/environments/{id}/deploy
Processor custom `DeployProcessor` dans `src/State/`.
- Charge l'Environment par id
- Valide que le tag est fourni
- Appelle `DeployService`
- Retourne le resultat
Response succes :
```json
{
"success": true,
"output": "==> Deploying sirh:v1.2.3...\n...\n==> Deployed v1.2.3",
"tag": "v1.2.3"
}
```
Response echec :
```json
{
"success": false,
"output": "Error: ...",
"tag": "v1.2.3"
}
```
### Docker
#### docker-compose.yml (dev)
Ajouter au service `php` :
```yaml
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
Note : en dev les deploy.sh ne sont pas forcement accessibles depuis le container (chemins host). Le deploy ne fonctionnera pleinement qu'en prod. En dev on peut tester la liste des tags et le mecanisme, mais le deploy lui-meme pourra echouer (script introuvable). C'est acceptable.
#### docker-compose.yml (prod)
Ajouter au service `app` :
```yaml
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/www/sirh/deploy:/var/www/sirh/deploy:ro
- /var/www/lesstime/deploy:/var/www/lesstime/deploy:ro
- /var/www/inventory/deploy:/var/www/inventory/deploy:ro
```
Le socket Docker + les dossiers deploy montes en read-only (le deploy.sh est execute, pas modifie). Le script execute `docker compose` qui passe par le socket.
Installer `docker-cli` dans le Dockerfile prod pour que les commandes `docker compose` fonctionnent depuis le container.
### Frontend
#### Modal de deploy
Sur la page detail (`/applications/{slug}`), chaque environnement affiche un bouton "Deployer".
Clic sur "Deployer" → ouvre une modal `AppModal` avec :
- Un select (ou liste) des tags disponibles, charges depuis `GET /api/applications/{slug}/tags`
- Loading skeleton pendant le chargement des tags
- Bouton "Deployer" qui POST sur `/api/environments/{id}/deploy`
- Pendant le deploy : le bouton passe en loading, on attend la reponse
- A la fin : affichage du resultat dans la modal
- Succes : message vert + output du script dans un bloc `<pre>`
- Echec : message rouge + output du script dans un bloc `<pre>`
#### Service frontend
`frontend/services/deploy.ts` :
- `getAvailableTags(slug: string)` : GET les tags
- `deploy(envId: number, tag: string)` : POST le deploy
`frontend/services/dto/deploy.ts` :
- Type `Tag` : `{ name: string, date: string }`
- Type `DeployResult` : `{ success: boolean, output: string, tag: string }`
#### i18n
Nouvelles cles dans `fr.json` pour la modal de deploy (titre, select, boutons, messages succes/echec).
## Hors scope
- Streaming temps reel du log de deploy
- Historique des deployments
- Rollback
- Version actuellement deployee (affichage)