8.2 KiB
Déploiement production (Synology DS220+ / DSM 7.3) — Astro → Nginx statique
✅ CANONIQUE — Procédure de référence “prod DS220+ / DSM 7.3”.
Toute modif de déploiement doit être faite ici, via PR sur Gitea/main (pas d’édition à la main en prod).
Périmètre : build Docker (Node→Nginx), blue/green 8081/8082, Reverse Proxy DSM, smoke, rollback.
Dépendances critiques : variables PUBLIC_GITEA_* (sinon “Proposer” part en 404/login loop).
Voir aussi : OPS-REFERENCE.md (index), OPS_COCKPIT.md (checklist), TROUBLESHOOTING.md (incidents).
Dernière mise à jour : 2026-02-01
Ce document décrit une mise en place stable sur NAS :
- build Astro dans une image (Node)
- runtime Nginx statique
- bascule blue/green via Reverse Proxy DSM
- tests fonctionnels (dont “Proposer” → Gitea)
1) Arborescence recommandée
Dossier racine “courant” :
/volume2/docker/archicratie-web/current(symlink vers la release active)
Contenu attendu :
Dockerfiledocker-compose.ymlnginx.conf.env- le code du site (package.json, src/, scripts/, etc.)
ops/(scripts de smoke, etc.)
Releases :
/volume2/docker/archicratie-web/releases/<YYYYmmdd-HHMMSS>/app
2) Pré-requis DSM
- DSM 7.3 avec accès SSH (admin)
- Docker / Container Manager installé
- Reverse Proxy DSM configuré (Portail des applications)
- Sortie Internet OK depuis le NAS (résolution DNS + accès registry)
3) Sécurité réseau (important)
On publie le site via HTTPS 443 sur DSM Reverse Proxy.
Les ports 8081/8082 :
- bindés en localhost uniquement (
127.0.0.1:8081:80,127.0.0.1:8082:80) - n’ont PAS besoin d’être ouverts dans le pare-feu WAN
- servent uniquement à DSM Reverse Proxy (loopback)
4) Variables Gitea (FEATURE “Proposer”)
Le site injecte des variables “publiques” au build :
PUBLIC_GITEA_BASE(URL gitea)PUBLIC_GITEA_OWNER(casse sensible)PUBLIC_GITEA_REPO
Exemple dans .env :
PUBLIC_GITEA_BASE=https://gitea.archicratie.trans-hands.synology.me
PUBLIC_GITEA_OWNER=Archicratia
PUBLIC_GITEA_REPO=archicratie-edition
4.1 Piège validé : mauvais owner/repo ⇒ 404/redirect
Symptômes typiques :
- nouvel onglet “Proposer” ouvre
/archicratia/archicratie-web/...(mauvais) - Gitea renvoie 404 “page inexistante ou non autorisé”
- ou 303
/user/login(si non loggé)
Contrôle rapide : en sh for f in .env .env.local .env.production .env.production.local; do [ -f "$f" ] && echo "---- $f" && grep -nE '^PUBLIC_GITEA_(BASE|OWNER|REPO)=' "$f" || true done
En cas d’échec :
- 404 / login loop / mauvais repo →
docs/TROUBLESHOOTING.md#proposer-404 - double onglet →
docs/TROUBLESHOOTING.md#proposer-double-onglet
Diagnostic — “Proposer” (résumé)
Symptôme : clic “Proposer” → 404 / login / mauvais repo
Cause la plus fréquente : PUBLIC_GITEA_OWNER (casse sensible) ou PUBLIC_GITEA_REPO faux.
➡️ Procédure complète (pas-à-pas + commandes) : voir docs/TROUBLESHOOTING.md#proposer-404.
5) Reverse Proxy DSM (le point clé)
DSM 7.3 :
Panneau de configuration → Portail des applications → Proxy inversé
Règle pour le site :
Source : HTTPS / archicratie.trans-hands.synology.me / port 443
Destination : HTTP / 127.0.0.1 / port 8081 (BLUE) ou 8082 (GREEN)
Certificat :
Sécurité → Certificat : associer le bon certificat au nom de domaine.
6) Notes DS220+ “spécificités”
6.1 Build réseau (DNS/apt/npm) : mode robuste
Sur DSM, il arrive que apt-get/npm aient des soucis réseau pendant docker build. Mesures robustes validées :
build en --network host
apt-get avec retries + ForceIPv4
Exemple (dans Dockerfile) :
apt-get -o Acquire::Retries=5 -o Acquire::ForceIPv4=true ...
6.2 BuildKit / buildx / API Docker (DSM)
Certains environnements DSM peuvent :
exiger BuildKit pour --network=host au build
avoir des incompatibilités d’API (client/daemon)
Standard “chez nous” :
activer BuildKit au build
utiliser DOCKER_API_VERSION="$API" si requis sur la machine
Remarque : la valeur de $API est celle validée localement sur le NAS.
6.3 Artefacts Mac (PaxHeader / ._ / DS_Store)
Si tu transfères une archive depuis macOS, tu peux embarquer des fichiers parasites. Conséquence possible : Astro “voit” un faux contenu → erreurs de schema.
Remède :
.dockerignore robuste (voir docs anchors / ops)
éviter les copies “tar” non nettoyées
7) Cycle blue/green (procédure protocolaire)
7.1 Identifier quel slot est actuellement “en prod”
Comparer l’ETag/Last-Modified public avec 8081/8082 : curl -kI https://archicratie.trans-hands.synology.me/ | egrep -i 'etag:|last-modified:|server:' curl -fsSI http://127.0.0.1:8081/ | egrep -i 'etag:|last-modified:' curl -fsSI http://127.0.0.1:8082/ | egrep -i 'etag:|last-modified:'
Le port qui “match” est le slot actif.
7.2 Déployer sur le slot inactif (ex: GREEN 8082)
Se placer sur le checkout courant :
cd /volume2/docker/archicratie-web/current || exit 1
Charger .env dans le shell (pour les build-args) :
set -a . ./.env set +a
Rebuild image (exemple green) :
sudo env DOCKER_BUILDKIT=1 DOCKER_API_VERSION="$API" docker build --no-cache --network host
--build-arg PUBLIC_GITEA_BASE="$PUBLIC_GITEA_BASE"
--build-arg PUBLIC_GITEA_OWNER="$PUBLIC_GITEA_OWNER"
--build-arg PUBLIC_GITEA_REPO="$PUBLIC_GITEA_REPO"
-t archicratie-web:green
-f Dockerfile .
Recreate conteneur (important) :
sudo docker compose up -d --force-recreate --no-build web_green
Smoke local :
/volume2/docker/archicratie-web/ops/smoke.sh 8082
Sanity check (fichiers clés) :
curl -fsSI http://127.0.0.1:8082/ | head -n 20 curl -fsSI http://127.0.0.1:8082/favicon.ico | head -n 20 curl -fsSI http://127.0.0.1:8082/favicon.svg | head -n 20
Contrôle “Proposer” (validation fonctionnelle)
Ouvrir une page chapitre sur le domaine public (ou sur le slot direct si tu testes en local)
Clic Proposer → choix 1 → choix 2
Attendus :
un seul onglet
URL sur .../Archicratia/archicratie-edition/issues/new?...
formulaire visible (si loggé sur Gitea)
issue créée et CI/runner OK (si configuré)
7.3 Bascule DSM
Dans DSM Reverse Proxy :
destination 8081 ↔ 8082 (BLUE ↔ GREEN)
7.4 Rollback (immédiat)
repointer DSM sur l’ancien port (1 clic)
analyser ensuite le slot inactif
8) Favicon (et faux positifs navigateur)
8.1 Symptom: Firefox affiche un 504 sur /favicon.ico
Cause fréquemment observée : cache navigateur (Firefox). Diagnose :
curl -kI https://.../favicon.ico renvoie 200
mais la console navigateur montre encore une erreur Fix :
désactiver le cache dans l’onglet Réseau, puis reload
ou vider le cache site
8.2 Permissions fichiers (si 403)
Si /favicon.svg renvoie 403 :
vérifier droits dans l’image nginx
standard : fichiers 644, répertoires 755 (validé via RUN find ... chmod)
9) Exploitation : log driver “db” et erreur “database is locked”
Erreur observée :
failed to initialize logging driver : database is locked
Contexte validé :
docker info → Logging Driver: db
Remède validé :
redémarrer Container Manager (centre de paquets DSM)
vérifier l’espace disque (df -h) et /tmp
Commandes : sudo docker info 2>/dev/null | egrep -i 'Logging Driver|Docker Root Dir|Server Version' || true df -h df -i
10) Références
Pour l’opérationnel minute par minute + tableau de bord : OPS_COCKPIT.md
Pour la synchro Mac/Gitea/NAS : OPS-SYNC-TRIPLE-SOURCE.md
Pour le workflow branches/PR/tags : WORKFLOW-GIT.md
Pour l’ENV : CONFIG-ENV.md
Pour les pannes connues : TROUBLESHOOTING.md
Depuis quelle machine tu fais ça ?
- Édition des docs : Mac Studio (éditeur confortable, git propre)
- Commit/push : Mac Studio (idéal), NAS seulement en “urgence”
- Déploiement : NAS (évidemment)
- Gitea docker : juste l’UI/Actions, pas nécessaire pour écrire les fichiers.
Et maintenant (ordre propre)
- Sur Mac : crée/complète ce doc (ci-dessus) + les autres docs.
- Commit “docs: ops runbooks (2026-02-01)” sur
main. - Push → CI verte.
- Sur NAS :
reset --hard origin/main(via alpine/git si besoin). - Rebuild/deploy uniquement si tu as touché Dockerfile/nginx/src/public (pas si docs only).