# 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://: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 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@ # 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://: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://:8973/`. ### 4. Premier chargement Si aucune tuile n'a encore été synchronisée, déclencher une première fois : ```bash curl -X POST http://:8973/api/sync ``` (puis attendre la fin : `curl http://: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).