235 lines
6.8 KiB
Markdown
235 lines
6.8 KiB
Markdown
# OPS_COCKPIT — Exploitation “cockpit” (DS220+ / DSM 7.3)
|
||
|
||
Dernière mise à jour : 2026-01-29
|
||
|
||
Objectif : déployer en **blue/green** (2 slots), basculer via **DSM Reverse Proxy**, rollback en ~10 secondes.
|
||
|
||
---
|
||
|
||
## 1) Repères (à ne pas confondre)
|
||
|
||
- Dossier NAS : `/volume2/docker/archicratie-web/current`
|
||
- Domaine site : `https://archicratie.trans-hands.synology.me`
|
||
- Gitea public : `https://gitea.archicratie.trans-hands.synology.me`
|
||
- Slot BLUE : conteneur `archicratie-web-blue` → `127.0.0.1:8081 -> 80`
|
||
- Slot GREEN : conteneur `archicratie-web-green` → `127.0.0.1:8082 -> 80`
|
||
- DSM Reverse Proxy pointe **soit** vers 8081 **soit** vers 8082 (c’est *ça* la bascule)
|
||
|
||
💡 Les couleurs n’ont pas de “sens métier”.
|
||
**Le slot pointé par DSM = PRODUCTION.** L’autre = pré-prod / candidat.
|
||
|
||
---
|
||
|
||
## 2) Commandes “état des lieux” (30 secondes)
|
||
|
||
en bash
|
||
cd /volume2/docker/archicratie-web/current
|
||
|
||
docker compose ps
|
||
docker inspect -f '{{.State.Health.Status}}' archicratie-web-blue
|
||
docker inspect -f '{{.State.Health.Status}}' archicratie-web-green
|
||
|
||
# Test local direct (depuis le NAS)
|
||
curl -I http://127.0.0.1:8081/ | head
|
||
curl -I http://127.0.0.1:8082/ | head
|
||
|
||
# Pour voir quelle version est SERVIE par DSM :
|
||
curl -kI https://archicratie.trans-hands.synology.me/ | head
|
||
|
||
## 3) Déploiement standard (build sur slot inactif)
|
||
|
||
Hypothèse : DSM pointe actuellement sur 8081 (BLUE) → on déploie sur GREEN (8082).
|
||
|
||
### 3.1 Pré-check (obligatoire)
|
||
cd /volume2/docker/archicratie-web/current
|
||
ls -la docker-compose.yml Dockerfile nginx.conf .env
|
||
cat .env
|
||
|
||
### 3.2 Build GREEN (image + dist + pagefind)
|
||
cd /volume2/docker/archicratie-web/current
|
||
|
||
export DOCKER_BUILDKIT=1
|
||
export COMPOSE_DOCKER_CLI_BUILD=1
|
||
|
||
docker compose build --no-cache web_green
|
||
|
||
### 3.3 Démarrer GREEN
|
||
docker compose up -d --force-recreate web_green
|
||
docker compose ps
|
||
|
||
### 3.4 Smoke test (GREEN)
|
||
./scripts/smoke.sh 8082
|
||
|
||
### 3.5 Health + logs (GREEN)
|
||
docker inspect -f '{{.State.Health.Status}}' archicratie-web-green
|
||
docker compose logs -f --tail=80 web_green
|
||
|
||
## 4) Basculer PROD (DSM) — 10 secondes
|
||
|
||
# Dans DSM 7.3 :
|
||
|
||
Panneau de configuration → Portail des applications → Proxy inversé
|
||
|
||
# Ouvre la règle du host :
|
||
|
||
Source : https / archicratie.trans-hands.synology.me / port 443
|
||
|
||
# Destination :
|
||
|
||
Protocole : http
|
||
|
||
Hôte : 127.0.0.1
|
||
|
||
Port : 8082 (pour basculer vers GREEN)
|
||
|
||
Enregistre.
|
||
|
||
# Validation rapide :
|
||
|
||
Dans ton navigateur : recharge le site (Ctrl+F5)
|
||
|
||
# Ou en shell :
|
||
curl -kI https://archicratie.trans-hands.synology.me/ | head
|
||
|
||
## 5) Rollback (si souci) — 10 secondes
|
||
|
||
Dans DSM → même écran → repasse Destination Port à 8081.
|
||
|
||
Optionnel (si GREEN est “pollué” / à arrêter) :
|
||
docker compose stop web_green
|
||
docker compose logs --tail=200 web_green
|
||
|
||
## 6) Dépannage “scénarios typiques”
|
||
### A) DSM renvoie HTTP 504 (timeout)
|
||
|
||
# Symptôme : curl -kI https://archicratie... → 504, et DSM affiche “noindex”.
|
||
|
||
# Causes probables
|
||
|
||
Le conteneur n’écoute pas / est down
|
||
|
||
Le port DSM ne correspond pas au bon slot
|
||
|
||
Bind local absent (ports mal écrits)
|
||
|
||
Santé KO (mais DSM bascule quand même et tombe sur un truc mort)
|
||
|
||
# Checklist
|
||
docker compose ps
|
||
curl -I http://127.0.0.1:8081/ | head
|
||
curl -I http://127.0.0.1:8082/ | head
|
||
docker compose logs --tail=200 web_blue
|
||
docker compose logs --tail=200 web_green
|
||
|
||
Dans DSM : vérifie Destination = http://127.0.0.1:808X
|
||
|
||
⚠️ Important : ne pas ouvrir 8081/8082 au WAN.
|
||
Le reverse proxy DSM accède en loopback. Les ports restent en local (127.0.0.1:...).
|
||
|
||
### B) Gitea : 404 sur la redirection “Proposer”
|
||
|
||
Ca arrive si OWNER/REPO n’existent pas, ou si la casse est mauvaise.
|
||
|
||
# 1) Vérifier les variables injectées
|
||
cat .env
|
||
|
||
# 2) Vérifier que le repo existe vraiment
|
||
BASE="https://gitea.archicratie.trans-hands.synology.me"
|
||
OWNER="Archicratia"
|
||
REPO="archicratie-edition"
|
||
|
||
curl -kI "$BASE/$OWNER/$REPO/" | head -n 12
|
||
|
||
# 3) Vérifier via API
|
||
curl -ks "$BASE/api/v1/users/$OWNER" | head -c 250; echo
|
||
curl -ks "$BASE/api/v1/users/$OWNER/repos?limit=100" | grep -o '"full_name":"[^"]*"' | head
|
||
|
||
# 4) Si c’est bon côté Gitea mais Proposer continue à viser l’ancien repo
|
||
→ tu as juste une image web construite avec les anciennes valeurs. Rebuild le slot.
|
||
|
||
docker compose build --no-cache web_green
|
||
docker compose up -d --force-recreate web_green
|
||
./scripts/smoke.sh 8082
|
||
|
||
# 5) Contrôle dans le HTML servi
|
||
docker exec -it archicratie-web-green sh -lc \
|
||
'grep -Rin "const GITEA_BASE" /usr/share/nginx/html | head -n 20'
|
||
|
||
### C) “Proposer” échoue (pas de ticket / pas de redirection)
|
||
|
||
# Cas typiques :
|
||
|
||
JS inline bloqué / non injecté
|
||
|
||
la page a été rebuild sans les variables publiques
|
||
|
||
erreur CORS / cookies / mauvais domaine (http vs https)
|
||
|
||
# Check rapide
|
||
|
||
Ouvre la console navigateur → onglet Network
|
||
|
||
Vérifie que la redirection pointe bien vers :
|
||
https://gitea.archicratie.../Archicratia/archicratie-edition/...
|
||
|
||
# Check côté build
|
||
docker exec -it archicratie-web-green sh -lc \
|
||
'grep -Rin "PUBLIC_GITEA" /usr/share/nginx/html | head -n 50'
|
||
|
||
### D) Pagefind ne marche plus (recherche vide / pagefind.js absent)
|
||
|
||
# Check HTTP
|
||
curl -I http://127.0.0.1:8082/pagefind/pagefind.js | head
|
||
|
||
# Check fichier dans le conteneur
|
||
docker exec -it archicratie-web-green sh -lc 'ls -la /usr/share/nginx/html/pagefind | head'
|
||
|
||
# Causes
|
||
|
||
build lancé via astro build au lieu de npm run build (donc postbuild non exécuté)
|
||
|
||
pagefind a échoué pendant postbuild
|
||
|
||
dist non généré / non copié dans nginx
|
||
|
||
# Remède
|
||
docker compose build --no-cache web_green
|
||
docker compose up -d --force-recreate web_green
|
||
./scripts/smoke.sh 8082
|
||
|
||
## 7) Logs “propres”
|
||
docker compose logs --tail=200 web_blue
|
||
docker compose logs --tail=200 web_green
|
||
|
||
# Si tu veux suivre en live :
|
||
docker compose logs -f web_green
|
||
|
||
|
||
## Historique synthétique (2026-03-03) — Stabilisation CI/CD “zéro surprise”
|
||
|
||
### Problème initial observé
|
||
- Déploiement parfois lancé en “hotpatch” alors qu’un rebuild était nécessaire.
|
||
- Sur merge commits, la détection de fichiers modifiés pouvait être ambiguë.
|
||
- Résultat : besoin de `force=1` manuel pour éviter des incohérences.
|
||
|
||
### Correctif appliqué
|
||
- Gate CI rendu **merge-proof** :
|
||
- lecture de `BEFORE` et `AFTER` depuis `event.json`
|
||
- calcul des fichiers modifiés via `git diff --name-only BEFORE AFTER`
|
||
|
||
- Politique de décision stabilisée :
|
||
- FULL auto dès qu’un changement impacte build/runtime (content/pages/scripts/anchors/etc.)
|
||
- HOTPATCH auto uniquement pour annotations/media
|
||
|
||
### Preuves
|
||
- Test A (touch src/content) :
|
||
- Gate flags: HAS_FULL=1 HAS_HOTPATCH=0 → MODE=full
|
||
- Test B (touch src/annotations) :
|
||
- Gate flags: HAS_FULL=0 HAS_HOTPATCH=1 → MODE=hotpatch
|
||
|
||
### Audit post-déploiement (preuves côté NAS)
|
||
- 8081 + 8082 répondent HTTP 200
|
||
- `/para-index.json` + `/annotations-index.json` OK
|
||
- Aliases injectés visibles dans HTML via `.para-alias` quand alias présent
|
||
|