# serveur_web_dorsal **Le serveur qui porte les sites et les applications web du locataire** : webapps dynamiques (runtime + service systemd) et, depuis le 2026-09-29, sites **statiques** (repris du web frontal). **100 % natif** — venv/paquets + systemd + nginx, **zéro conteneur**. Codifié depuis le spike du 2026-07-05 (monregistraire : FastAPI + uvicorn + SQLite ; site Alliance Boréale). Il est relayé par **deux portes** : l'**edge** pour les noms internes (l'administration), le **web frontal** (reverse proxy + WAF) pour les noms publics (l'Internet). ## Patron Pour chaque app déclarée dans `serveur_web_dorsal_apps` : 1. `git clone` (depth 1) → `/srv/webapp/` ; 2. venv Python + `pip install -r requirements.txt` ; 3. **unité systemd** (l'app écoute en `127.0.0.1:`, user `webapp`, durcie : NoNewPrivileges, PrivateTmp) ; 4. **vhost nginx local** qui fronte l'app (`server_name` → `127.0.0.1:`). L'app reste **en localhost** (sûr) ; l'edge proxie `server_name` → nginx local → app. Exposé via `applications.yml` (port **80**, pas le port interne de l'app). ## Déclaration (group_vars du groupe serveur_web_dorsal) ```yaml serveur_web_dorsal_apps: - nom: registraire server_name: "registraire.{{ domaine_interne }}" depot: "https://forge.{{ domaine_interne }}/…/monregistraire.git" branche: main port: 8001 commande: ".venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8001" env: { IMMOS_DB_PATH: /var/lib/registraire/immos.db } data_dir: /var/lib/registraire # état local (SQLite), optionnel ``` Et une app `groupe: serveur_web_dorsal, hote: , port: 80, expose: [registraire.]`. ## Sites statiques Pour chaque site déclaré dans `serveur_web_dorsal_sites` : `git clone`/`pull` → `/srv/web/`, puis un vhost nginx servant `` (ex. `public/`), avec en-têtes de sécurité + CSP (défaut : `self` only, aucun tiers), gzip, cache. ```yaml serveur_web_dorsal_sites: - nom: alliance server_name: "alliance-boreale.chezlepro.ca" # le FQDN que le plan expose depot: "https://forge.{{ domaine_interne }}/alliance/site-alliance-boreale.git" branche: main sous_dossier: public ``` Et dans `applications.yml` : `groupe: serveur_web_dorsal, hote: , port: 80, expose: []`. Sonde `sites-servis` : un GET par `server_name`. ## BD Les apps à état **local** (SQLite) : `data_dir` persistant. Les apps à **BD réseau** (PostgreSQL) : déclarer la base dans `bases-donnees.yml` et passer le DSN via `env` (resoudre_base) — même motif que les autres services Set-OPS. ## Runtimes Éprouvé sur **Python (FastAPI/uvicorn)**. Node/autres : adapter `commande` + les paquets de runtime (le patron systemd + nginx + git reste identique). ## Validation `ansible-lint` profil production + `--syntax-check`. Éprouvé sur web-frontal-01 (monregistraire servi via l'edge, HTTPS step-ca, API fonctionnelle) — avant que le frontal ne devienne le reverse proxy public.