docs(luz): documenter le déploiement two-env par script SSH

Home : luz avec /api backend + ajout luz-dev. Installation-Production :
section 7 réécrite (2 environnements, script deploy.sh, secret JWT_SECRET).
Mise-a-jour : procédure update/rollback par script, dump BDD prod, exclusion
de luz de la boucle pull registre.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 05:22:34 +02:00
parent f3ee7979ec
commit f3de8d7fa4
3 changed files with 71 additions and 14 deletions
+6 -2
@@ -15,7 +15,10 @@ Internet
├── bonsai.goutailler-olivier.com ├── bonsai.goutailler-olivier.com
│ ├── /api → Bonsai API (Spring Boot) │ ├── /api → Bonsai API (Spring Boot)
│ └── / → Bonsai Webapp (front-end) │ └── / → Bonsai Webapp (front-end)
├── luz.goutailler-olivier.com → Luz (front-end Angular) ├── luz.goutailler-olivier.com
│ ├── /api → Luz Backend (Spring Boot)
│ └── / → Luz Webapp (Angular)
├── luz-dev.goutailler-olivier.com → Luz (env. de TEST : webapp + /api backend, BDD seed)
├── cloud.goutailler-olivier.com → Nextcloud ├── cloud.goutailler-olivier.com → Nextcloud
├── notes.goutailler-olivier.com → Trilium ├── notes.goutailler-olivier.com → Trilium
├── olhar.goutailler-olivier.com ├── olhar.goutailler-olivier.com
@@ -33,7 +36,8 @@ Internet
| Keycloak | `keycloak/` | `auth.goutailler-olivier.com` | | Keycloak | `keycloak/` | `auth.goutailler-olivier.com` |
| Bonsai API | `bonsai-api/` | `bonsai.goutailler-olivier.com/api` | | Bonsai API | `bonsai-api/` | `bonsai.goutailler-olivier.com/api` |
| Bonsai Webapp | `bonsai-webapp/` | `bonsai.goutailler-olivier.com` | | Bonsai Webapp | `bonsai-webapp/` | `bonsai.goutailler-olivier.com` |
| Luz | `luz/` | `luz.goutailler-olivier.com` | | Luz (prod) | `luz/` | `luz.goutailler-olivier.com` (webapp + `/api` backend + BDD) |
| Luz (test) | `luz-dev/` | `luz-dev.goutailler-olivier.com` (webapp + `/api` backend + BDD seed) |
| Nextcloud | `nextcloud/` | `cloud.goutailler-olivier.com` | | Nextcloud | `nextcloud/` | `cloud.goutailler-olivier.com` |
| Trilium | `trilium/` | `notes.goutailler-olivier.com` | | Trilium | `trilium/` | `notes.goutailler-olivier.com` |
| Olhar | `olhar/` | `olhar.goutailler-olivier.com` (API + PWA + BDD) | | Olhar | `olhar/` | `olhar.goutailler-olivier.com` (API + PWA + BDD) |
+24 -7
@@ -149,19 +149,36 @@ L'image `git.goutailler-olivier.com/bonsai/bonsai-webapp:latest` est également
## 7. Luz ## 7. Luz
Luz est déployé en **deux environnements**, chacun servant à la fois la webapp Angular et le backend Spring Boot sur un même domaine (routing par chemin Traefik) :
| Env. | Dossier | Domaine | Backend | Base de données |
|---|---|---|---|---|
| Production | `luz/` | `luz.goutailler-olivier.com` | `/api` | persistante (`~/Applications/data/luz/db_data`) |
| Test | `luz-dev/` | `luz-dev.goutailler-olivier.com` | `/api` | réinitialisée à chaque boot (profil Spring `dev` + `seed.sql`) |
Chaque stack contient trois services : `db` (PostgreSQL 17), `backend` (`localhost/luz-backend`) et `webapp` (`localhost/luz-webapp`, nginx).
**Déploiement par script (SSH direct, sans registre).** Contrairement aux autres services, les images Luz ne transitent **pas** par le registre Gitea / Watchtower : elles sont buildées en local puis chargées sur le serveur par SSH via `Luz/script/deploy.sh` (voir [Mise à jour des applications](Mise-a-jour-Applications)).
```bash ```bash
cd luz/ # Depuis le repo Luz, en local :
docker compose up -d cp deploy/deploy.env.example deploy/deploy.env # renseigner SSH_HOST / SSH_USER
./script/deploy.sh prod # build + envoi + démarrage (prod)
./script/deploy.sh dev # idem sur l'environnement de test
``` ```
L'image `git.goutailler-olivier.com/gato/luz:latest` est construite par la CI Gitea lors d'une release. Aucune variable d'environnement spécifique n'est requise. Au **premier déploiement**, le script crée le dossier distant (`~/luz` ou `~/luz-dev`), y copie le `docker-compose.yml` et **génère un `.env`** avec des secrets forts (jamais écrasé ensuite).
**Secrets Gitea à configurer au niveau de l'organisation `gato` :** Variables du `.env` (générées automatiquement, ou à définir pour un démarrage manuel) :
| Secret | Description | | Variable | Description |
|---|---| |---|---|
| `RELEASE_TOKEN` | Token Gitea avec droits `write:packages` et `write:repository` | | `DB_PASSWORD` | Mot de passe PostgreSQL — `openssl rand -hex 16` |
| `WATCHTOWER_TOKEN` | Token HTTP de l'API Watchtower pour déclencher le redéploiement (voir section 11) | | `JWT_SECRET` | Secret de signature JWT — `openssl rand -base64 32`. **Obligatoire** : ne jamais réutiliser le défaut de développement de `application.yml` sur un domaine public. |
**Prérequis DNS :** enregistrements A `luz` et `luz-dev` pointant sur le serveur (indispensables au challenge HTTP-01 de Let's Encrypt).
Flyway applique les migrations au démarrage du backend. En prod, la base est persistante ; en test (profil `dev`), elle est réinitialisée avec les données de seed à chaque redémarrage.
--- ---
+41 -5
@@ -152,11 +152,46 @@ docker start bonsai-api
--- ---
## Rollback Luz ## Luz — déploiement par script (SSH direct, sans registre)
1. Aller dans **Gitea → Luz → Actions → Rollback → Run workflow** Luz ne suit **pas** le flux registre + Watchtower : le backend et la webapp sont buildés en local puis envoyés au serveur par SSH avec `Luz/script/deploy.sh`. Il n'y a donc ni `docker compose pull`, ni image versionnée sur le registre.
2. Saisir la version cible (ex. `v1.2.3`)
3. Lancer — Watchtower redéploie automatiquement ### Mettre à jour (dev ou prod)
Depuis le repo Luz, en local :
```bash
./script/deploy.sh prod # rebuild + envoi + up des 2 images (prod)
./script/deploy.sh prod backend # backend seul
./script/deploy.sh prod webapp # webapp seule
./script/deploy.sh dev # environnement de test
```
Le script build l'image concernée, la transfère (`podman save | gzip | ssh 'docker load'`), resynchronise le `docker-compose.yml` et fait `docker compose up -d`. Comme l'image rechargée a un nouvel ID sous le même tag, `up -d` recrée le conteneur. Indisponibilité limitée au redémarrage (quelques secondes).
### Commandes de gestion
```bash
./script/deploy.sh prod status # docker compose ps
./script/deploy.sh prod logs backend # suit les logs
./script/deploy.sh prod down # arrête le stack (volumes/données conservés)
```
### Rollback
Sans registre, on rejoue une version antérieure **depuis le code** : se placer sur le commit/tag voulu et redéployer.
```bash
git -C ~/Workspace/Luz checkout <tag-ou-commit>
./script/deploy.sh prod
git -C ~/Workspace/Luz checkout main
```
> **Base de données (prod).** La base prod est persistante et il n'existe pas (encore) de backup automatique comme pour Bonsai/Olhar. Avant un déploiement à risque (migration Flyway destructive), faire un dump manuel :
> ```bash
> ssh <serveur> 'docker exec luz-db pg_dump -U luz luz | gzip' > luz_$(date +%F).sql.gz
> ```
> En environnement **test** (`dev`), la base est réinitialisée à chaque boot : aucun rollback de données à prévoir.
--- ---
@@ -185,7 +220,8 @@ Les backups sont stockés dans `/opt/backups/olhar/` sur le serveur.
## Mettre à jour tous les services d'un coup ## Mettre à jour tous les services d'un coup
```bash ```bash
for dir in traefik keycloak gitea bonsai-api bonsai-webapp luz olhar nextcloud trilium; do # Note : luz / luz-dev sont exclus — ils se déploient via Luz/script/deploy.sh (pas de pull registre).
for dir in traefik keycloak gitea bonsai-api bonsai-webapp olhar nextcloud trilium; do
echo "=== $dir ===" echo "=== $dir ==="
(cd "$dir" && docker compose pull && docker compose up -d) (cd "$dir" && docker compose pull && docker compose up -d)
done done