mirror of
https://github.com/siop-spelev/siop2.git
synced 2026-08-08 12:41:54 +00:00
ci(r0.13): déploiement continu Dokploy — instance siop2.apps.enset.top
- job deploy : webhook Dokploy appelé sur push main uniquement si les 5 jobs CI sont verts ; skip explicite tant que DOKPLOY_WEBHOOK_URL n'est pas configuré - runbook : instance de démonstration ENSET, checklist de déploiement manuel depuis GitHub (§3) et mise en place du CD (§4) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
23
.github/workflows/ci.yml
vendored
23
.github/workflows/ci.yml
vendored
@@ -155,3 +155,26 @@ jobs:
|
|||||||
name: playwright-report
|
name: playwright-report
|
||||||
path: apps/web/playwright-report/
|
path: apps/web/playwright-report/
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
|
# Déploiement continu (runbook §4) : Dokploy reconstruit et redéploie le
|
||||||
|
# compose UNIQUEMENT quand les 5 verrous sont verts sur main. Le webhook
|
||||||
|
# vit dans le secret DOKPLOY_WEBHOOK_URL (Dokploy → service compose →
|
||||||
|
# Deployments → Webhook URL) ; tant qu'il n'est pas configuré, le job
|
||||||
|
# se termine en « skip » sans faire échouer le pipeline.
|
||||||
|
deploy:
|
||||||
|
name: deploy (Dokploy — siop2.apps.enset.top)
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
|
needs: [lint, contract, api, web, e2e]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: production
|
||||||
|
steps:
|
||||||
|
- name: Déclencher le déploiement Dokploy
|
||||||
|
env:
|
||||||
|
WEBHOOK_URL: ${{ secrets.DOKPLOY_WEBHOOK_URL }}
|
||||||
|
run: |
|
||||||
|
if [ -z "$WEBHOOK_URL" ]; then
|
||||||
|
echo "::notice::DOKPLOY_WEBHOOK_URL absent — déploiement sauté (configurer le secret pour activer le CD)."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
curl -fsS -X POST "$WEBHOOK_URL"
|
||||||
|
echo "Déploiement déclenché — suivi : Dokploy → Deployments."
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
# Runbook — déploiement Dokploy
|
# Runbook — déploiement Dokploy
|
||||||
|
|
||||||
> **Rôle de ce document (playbook)** : la procédure REJOUABLE de mise en production
|
> **Rôle de ce document (playbook)** : la procédure REJOUABLE de mise en production
|
||||||
> sur Dokploy (PaaS auto-hébergé du partenaire), écrite en R0.13 et répétée à chaque
|
> sur Dokploy, écrite en R0.13 et répétée à chaque release (principe « déployer tôt »).
|
||||||
> release (principe « déployer tôt »). Statut : **répété en local, en attente des
|
>
|
||||||
> accès au serveur du partenaire** pour la première exécution réelle.
|
> **Instances** : démonstration/cours → `https://siop2.apps.enset.top` (Dokploy ENSET,
|
||||||
|
> projet créé le 15/07/2026) ; production client SPELEV → en attente des accès au
|
||||||
|
> serveur du partenaire (même procédure, profil d'environnement « production client »).
|
||||||
|
|
||||||
## 1. Topologie
|
## 1. Topologie
|
||||||
|
|
||||||
Un projet Dokploy = un service « Compose » pointant sur ce dépôt,
|
Un projet Dokploy = un service « Compose » pointant sur ce dépôt,
|
||||||
fichier [`infra/docker-compose.dokploy.yml`](../../infra/docker-compose.dokploy.yml) :
|
fichier [`infra/docker-compose.dokploy.yml`](../../infra/docker-compose.dokploy.yml) :
|
||||||
|
|
||||||
```
|
```text
|
||||||
domaine (Traefik/Dokploy) ──▶ siop2-web :80 (nginx, statique)
|
domaine (Traefik/Dokploy) ──▶ siop2-web :80 (nginx, statique)
|
||||||
│ /api/** (préfixe retiré)
|
│ /api/** (préfixe retiré)
|
||||||
▼
|
▼
|
||||||
@@ -48,27 +50,58 @@ Profils types :
|
|||||||
- **Instance de démonstration** : `DEMO_MODE=true`, `DEMO_MODE_I_KNOW=true`,
|
- **Instance de démonstration** : `DEMO_MODE=true`, `DEMO_MODE_I_KNOW=true`,
|
||||||
`SEED_ON_START=true`.
|
`SEED_ON_START=true`.
|
||||||
|
|
||||||
## 3. Première mise en production (checklist)
|
## 3. Première mise en production — déploiement manuel depuis GitHub (checklist)
|
||||||
|
|
||||||
1. Dokploy → **Create Project** `siop2` → **Compose** ; source = dépôt
|
Dans le service **Compose** du projet Dokploy (déjà créé pour l'instance ENSET) :
|
||||||
`siop-spelev/siop2`, branche `main`, fichier `infra/docker-compose.dokploy.yml`.
|
|
||||||
2. Renseigner les variables d'environnement (§2) dans l'onglet Environment.
|
1. **Onglet General — source GitHub** : Provider `GitHub` (application GitHub
|
||||||
3. **Deploy**. Dokploy construit les images (contexte = racine du dépôt,
|
Dokploy autorisée sur `siop-spelev/siop2`, dépôt privé), Branch `main`,
|
||||||
Dockerfiles `apps/api` et `apps/web`) puis démarre les 5 services ;
|
**Compose Path** `infra/docker-compose.dokploy.yml`.
|
||||||
l'API attend PostgreSQL/Redis/MinIO sains (healthchecks) et migre la base.
|
2. **Onglet Environment** : coller les variables du §2. Pour l'instance de
|
||||||
4. Onglet Domains du service `siop2-web` : associer le domaine (port **80**,
|
démonstration ENSET :
|
||||||
HTTPS Let's Encrypt géré par Dokploy).
|
|
||||||
|
```env
|
||||||
|
POSTGRES_PASSWORD=<openssl rand -hex 24>
|
||||||
|
MINIO_ROOT_PASSWORD=<openssl rand -hex 24>
|
||||||
|
JWT_SECRET=<openssl rand -hex 32>
|
||||||
|
DEMO_MODE=true
|
||||||
|
DEMO_MODE_I_KNOW=true
|
||||||
|
SEED_ON_START=true
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Deploy** (bouton). Dokploy clone le dépôt, construit les images (contexte =
|
||||||
|
racine, Dockerfiles `apps/api` et `apps/web` — ~5-10 min au premier build) puis
|
||||||
|
démarre les 5 services ; l'API attend PostgreSQL/Redis/MinIO sains et migre la base.
|
||||||
|
Suivi : onglet **Deployments** (logs de build) puis **Logs** par service.
|
||||||
|
4. **Onglet Domains** : Add Domain → Host `siop2.apps.enset.top`,
|
||||||
|
**Service Name `siop2-web`**, **Container Port `80`**, HTTPS activé
|
||||||
|
(certificat Let's Encrypt géré par Dokploy/Traefik).
|
||||||
5. Vérifications :
|
5. Vérifications :
|
||||||
- `https://<domaine>/api/health` → `{"status":"ok", ...}` (les 3 services `up`) ;
|
- `https://siop2.apps.enset.top/api/health` → `{"status":"ok", ...}` (3 services `up`) ;
|
||||||
- production client : `https://<domaine>/api/auth/demo-accounts` → **404** ;
|
- écran de connexion : 7 comptes démo, bascule de rôle < 3 s, bi-thème ;
|
||||||
- instance démo : écran de connexion avec les 7 comptes, bascule de rôle < 3 s.
|
- production client (quand elle existera) : `/api/auth/demo-accounts` → **404**.
|
||||||
6. Consigner la mise en production dans `docs/journal/journal.md` (date, version, domaine).
|
6. Consigner la mise en production dans `docs/journal/journal.md` (date, commit, domaine).
|
||||||
|
|
||||||
## 4. Releases suivantes
|
## 4. Releases suivantes — déploiement continu par GitHub Actions
|
||||||
|
|
||||||
`git push` sur `main` (CI verte exigée) → Dokploy **Deploy** (ou webhook auto-deploy).
|
Le job `deploy` de `.github/workflows/ci.yml` appelle le **webhook Dokploy**
|
||||||
Les migrations de la release s'appliquent au démarrage ; en cas d'échec de migration,
|
à chaque push sur `main`, **uniquement si les 5 jobs (lint, contrat, api, web, e2e)
|
||||||
le conteneur s'arrête **sans** servir de trafic (l'ancienne version reste visible côté web).
|
sont verts** — c'est la CI qui garde la porte, pas l'inverse. Mise en place (une fois) :
|
||||||
|
|
||||||
|
1. Dokploy → service compose → onglet **Deployments** → copier la **Webhook URL**.
|
||||||
|
2. Dépôt GitHub → Settings → Secrets and variables → Actions →
|
||||||
|
**New repository secret** : nom `DOKPLOY_WEBHOOK_URL`, valeur = l'URL copiée.
|
||||||
|
(Ou en CLI : `gh secret set DOKPLOY_WEBHOOK_URL`.)
|
||||||
|
3. C'est tout : le prochain push vert sur `main` déclenche le build + redéploiement
|
||||||
|
côté Dokploy. Tant que le secret n'existe pas, le job `deploy` se termine en
|
||||||
|
« skip » explicite sans faire échouer le pipeline.
|
||||||
|
|
||||||
|
> **Ne pas activer** l'« Auto Deploy » natif de Dokploy (webhook GitHub direct) :
|
||||||
|
> il déploierait aussi les commits dont la CI est rouge.
|
||||||
|
|
||||||
|
Les migrations de la release s'appliquent au démarrage du conteneur API ; en cas
|
||||||
|
d'échec de migration, le conteneur s'arrête **sans** servir de trafic (l'ancienne
|
||||||
|
version reste visible côté web).
|
||||||
|
|
||||||
## 5. Incidents & retours arrière
|
## 5. Incidents & retours arrière
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,18 @@ Trace chronologique des sessions (la plus récente en premier). Le **playbook**
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-07-15 — Pr. Daaif (+ Claude) — R0.13 (suite) : instance ENSET + déploiement continu
|
||||||
|
|
||||||
|
**Actions**
|
||||||
|
|
||||||
|
- **Instance de démonstration décidée** : `https://siop2.apps.enset.top` (Dokploy ENSET, projet compose créé par le référent) — la production client SPELEV suivra la même procédure avec le profil « production client ».
|
||||||
|
- Job **`deploy`** ajouté au pipeline : appelle le webhook Dokploy sur push `main` **uniquement si lint + contrat + api + web + e2e sont verts** ; « skip » explicite tant que le secret `DOKPLOY_WEBHOOK_URL` n'est pas configuré. L'« Auto Deploy » natif de Dokploy reste désactivé (il ignorerait la CI).
|
||||||
|
- Runbook §3 réécrit en checklist concrète (source GitHub, Compose Path, variables du profil démo, domaine → `siop2-web:80`) et §4 en procédure CD (secret webhook).
|
||||||
|
|
||||||
|
**Prochaine étape** : premier déploiement manuel (runbook §3), pose du secret `DOKPLOY_WEBHOOK_URL` (§4), vérification `https://siop2.apps.enset.top/api/health`, puis recette R0 avec le référent sur l'instance en ligne.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 2026-07-15 — Pr. Daaif (+ Claude) — R0.12 (2/2) : ESLint + parcours Playwright — R0.12 CLOS
|
## 2026-07-15 — Pr. Daaif (+ Claude) — R0.12 (2/2) : ESLint + parcours Playwright — R0.12 CLOS
|
||||||
|
|
||||||
**Actions**
|
**Actions**
|
||||||
|
|||||||
Reference in New Issue
Block a user