Files
Central/docs/superpowers/specs/2026-04-06-phase2a-deploy-versions-design.md
tristan 8f585b4be8
All checks were successful
Auto Tag Develop / tag (push) Successful in 6s
feat/ajout-de-fonctionnalites (#1)
Reviewed-on: #1
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
2026-04-06 14:23:20 +00:00

5.5 KiB

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 :

{
    "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 :

{
    "success": true,
    "output": "==> Deploying sirh:v1.2.3...\n...\n==> Deployed v1.2.3",
    "tag": "v1.2.3"
}

Response echec :

{
    "success": false,
    "output": "Error: ...",
    "tag": "v1.2.3"
}

Docker

docker-compose.yml (dev)

Ajouter au service php :

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 :

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)