Split webapp for Raspberry Pi deployment, remote generation API and sync
La webapp (carte + vignettes) et la génération de tuiles se déploient sur deux machines : image légère Dockerfile.webapp (FastAPI + Pillow AVIF natif + pyproj) sur Raspberry Pi, pipeline complet sur la machine de traitement. LIDAR_GENERATION_URL délègue /api/generate, /api/preview et /api/status ; /api/sync ramène les tuiles par rsync puis régénère vignettes et index localement. Token partagé optionnel (LIDAR_API_TOKEN/LIDAR_REMOTE_TOKEN). Retire du dépôt les journaux internes (.swival, audit-findings) et les données (data/, notebooks/). Doc : docs/DEPLOY_WEBAPP.md.
This commit is contained in:
115
docs/DEPLOY_WEBAPP.md
Normal file
115
docs/DEPLOY_WEBAPP.md
Normal file
@ -0,0 +1,115 @@
|
||||
# Déploiement webapp légère + machine de traitement
|
||||
|
||||
Architecture deux machines : la **webapp** (carte interactive, vignettes,
|
||||
API) tourne sur un Raspberry Pi ; la **génération de tuiles** (téléchargement
|
||||
IGN, PDAL, GPU) tourne sur une machine puissante. Les deux exécutent le même
|
||||
code (`lidar_pipeline.webapp`), dans deux images Docker différentes.
|
||||
|
||||
```
|
||||
Navigateur ──HTTP──▶ Raspberry Pi (image légère, Dockerfile.webapp)
|
||||
│ sert carte + vignettes (régénérées localement)
|
||||
│ /api/generate, /api/preview, /api/status
|
||||
│ └─ transmis à ──▶ machine de traitement
|
||||
│ /api/sync : rsync output/ ──◀── machine puissante
|
||||
▼
|
||||
Machine puissante (image complète, docker-compose.yml
|
||||
service `serve`) : téléchargement IGN + pipeline GPU
|
||||
```
|
||||
|
||||
## Machine de traitement (puissante)
|
||||
|
||||
Le service `serve` existant joue le rôle de worker : il accepte les demandes
|
||||
de génération envoyées par la webapp du Pi.
|
||||
|
||||
```bash
|
||||
docker compose up -d --build serve # carte + API sur http://<ip-machine>:8973
|
||||
```
|
||||
|
||||
Optionnel mais recommandé si le réseau n'est pas de confiance : protéger les
|
||||
routes mutantes avec un jeton partagé — décommenter dans `docker-compose.yml` :
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
- LIDAR_API_TOKEN=un-secret-à-partager
|
||||
```
|
||||
|
||||
## Raspberry Pi (webapp légère)
|
||||
|
||||
### 1. Copier le code sur le Pi
|
||||
|
||||
```bash
|
||||
git clone <ce-dépôt> lidar && cd lidar # ou rsync du poste de dev
|
||||
```
|
||||
|
||||
### 2. Accès SSH pour le rsync (la Pi tire les tuiles traitées)
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 # si pas encore de clé
|
||||
ssh-copy-id lidar@<ip-machine> # compte lecture sur output/
|
||||
```
|
||||
|
||||
Sur la machine puissante, le dossier `output/` doit être lisible par ce
|
||||
compte (ex. `/srv/lidar/output` si vous préférez un chemin dédié — adaptez
|
||||
LIDAR_SYNC_CMD).
|
||||
|
||||
### 3. Configurer et lancer
|
||||
|
||||
Éditer `docker-compose.webapp.yml` :
|
||||
|
||||
- `LIDAR_GENERATION_URL` : `http://<ip-machine>:8973`
|
||||
- `LIDAR_REMOTE_TOKEN` : la valeur de `LIDAR_API_TOKEN` de la machine
|
||||
(inutile si aucun token là-bas)
|
||||
- `LIDAR_SYNC_CMD` : la commande rsync qui copie `output/` distant vers
|
||||
`/data/output/` local, ex :
|
||||
|
||||
```yaml
|
||||
- LIDAR_SYNC_CMD=rsync -a --delete --exclude=*.tif --exclude=.generation* --exclude=index_thumbs --exclude=index_subtiles lidar@192.168.1.50:/srv/lidar/output/ /data/output/
|
||||
```
|
||||
|
||||
Les vignettes (`index_thumbs/`, `index_subtiles/`) ne se synchronisent pas :
|
||||
elles sont régénérées sur place par le Pi (`/api/sync` → `build_index`),
|
||||
c'est le seul travail lourd qu'il fait. Exclure `*.tif` évite de copier des
|
||||
intermédiaires éventuels ; les sidecars `output/DTM/*_method.txt` servent au
|
||||
panneau d'infos et sont synchronisés.
|
||||
|
||||
```bash
|
||||
mkdir -p output
|
||||
docker compose -f docker-compose.webapp.yml up -d --build
|
||||
```
|
||||
|
||||
La carte est sur `http://<ip-pi>:8973/`.
|
||||
|
||||
### 4. Premier chargement
|
||||
|
||||
Si aucune tuile n'a encore été synchronisée, déclencher une première fois :
|
||||
|
||||
```bash
|
||||
curl -X POST http://<ip-pi>:8973/api/sync
|
||||
```
|
||||
|
||||
(puis attendre la fin : `curl http://<ip-pi>:8973/api/sync` → `"running":
|
||||
false`.) Le bouton ↻ de la carte fait la même chose (sync + vignettes).
|
||||
|
||||
## Fonctionnement
|
||||
|
||||
- Dessiner une zone (bouton « + Zone ») sur la carte du Pi envoie la demande
|
||||
à la machine de traitement, qui télécharge les dalles IGN puis les traite.
|
||||
La file de génération (progression tuile par tuile) est lue depuis la
|
||||
machine distante en direct.
|
||||
- À la fin du run, le navigateur appelle `/api/sync` : rsync ramène les
|
||||
images, le Pi régénère vignettes/sous-tuiles/index.html, puis recharge la
|
||||
carte. Le bouton ↻ relance le même cycle à tout moment.
|
||||
- Machine de traitement seule (sans Pi) : rien ne change, `--serve` /
|
||||
`docker compose up serve` fonctionne comme avant en local.
|
||||
- Si la machine de traitement est éteinte, la carte du Pi reste consultable
|
||||
(données synchronisées) ; seuls les nouveaux traitements sont indisponibles
|
||||
(message « machine de traitement injoignable »).
|
||||
|
||||
## Références
|
||||
|
||||
- `lidar_pipeline/webapp.py` : proxy distant (`LIDAR_GENERATION_URL`),
|
||||
`/api/sync`, jeton `LIDAR_API_TOKEN`/`LIDAR_REMOTE_TOKEN`.
|
||||
- `lidar_pipeline/index.py` : vignettes/index sans GDAL (pyproj ou repli
|
||||
affine), recharge après sync.
|
||||
- `Dockerfile.webapp`, `docker-compose.webapp.yml` : image légère ARM64
|
||||
(FastAPI + Pillow AVIF natif + pyproj, ~200 Mo).
|
||||
Reference in New Issue
Block a user