# Déployer lage-chat-control sur un VPS Le site est **100 % statique** (ADR-001) : le déploiement consiste à poser le contenu du dossier `frontend/build/` derrière un serveur web. Pas de base de données, pas de service Node à maintenir, pas de tâche cron. Un miroir du site = une copie du dossier. ## 0. Prérequis - Un VPS (1 vCPU / 512 Mo suffisent très largement) sous Debian/Ubuntu - Un nom de domaine pointant sur le VPS (enregistrement A/AAAA) - En local : Node ≥ 22.12 et pnpm (le build se fait **sur ta machine**, le VPS n'a besoin ni de Node ni de pnpm) ## 1. Construire le site ```sh git clone https://labola.o-k-i.net/cyber-mawonaj/lage-chat-control.git cd lage-chat-control/frontend pnpm install pnpm build # produit frontend/build/ (~60 pages statiques) ``` ## 2. Option A — Caddy (recommandé : TLS automatique) ```sh # sur le VPS sudo apt install caddy sudo mkdir -p /srv/lage-chat-control ``` `/etc/caddy/Caddyfile` : ```caddy exemple.o-k-i.net { root * /srv/lage-chat-control file_server encode zstd gzip # SvelteKit adapter-static : pages pré-générées + fallback try_files {path} {path}.html {path}/index.html /404.html header { # le service worker doit pouvoir se mettre à jour Cache-Control "no-cache" /service-worker.js # assets immuables (noms hachés) Cache-Control "public, max-age=31536000, immutable" /_app/immutable/* # en-têtes de sécurité Strict-Transport-Security "max-age=31536000; includeSubDomains" X-Content-Type-Options "nosniff" Referrer-Policy "no-referrer" Permissions-Policy "camera=(), microphone=(), geolocation=()" # CSP stricte : le site n'a aucune dépendance externe Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'" } } ``` Le TLS (Let's Encrypt) est automatique, rien d'autre à faire. ## 3. Option B — nginx ```sh sudo apt install nginx certbot python3-certbot-nginx ``` `/etc/nginx/sites-available/lage-chat-control` : ```nginx server { server_name exemple.o-k-i.net; root /srv/lage-chat-control; index index.html; # pages pré-générées : /outils → outils.html, fallback 404 location / { try_files $uri $uri.html $uri/index.html /404.html; } location /_app/immutable/ { add_header Cache-Control "public, max-age=31536000, immutable"; } location = /service-worker.js { add_header Cache-Control "no-cache"; } add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'" always; gzip on; gzip_types text/html text/css application/javascript application/json image/svg+xml; } ``` ```sh sudo ln -s /etc/nginx/sites-available/lage-chat-control /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx sudo certbot --nginx -d exemple.o-k-i.net # TLS ``` ## 4. Publier (et republier) ```sh # depuis ta machine, après chaque `pnpm build` rsync -avz --delete frontend/build/ vps:/srv/lage-chat-control/ ``` C'est l'intégralité du « pipeline de déploiement ». Pour automatiser : un runner Forgejo Actions sur labola peut exécuter build + rsync à chaque push sur `main` (à ajouter quand le besoin se présente, pas avant). ## 5. Option C — YunoHost Le site s'installe avec l'app **`my_webapp`** (site statique) : 1. Installe `my_webapp` depuis le catalogue, choisis le domaine/chemin. 2. Copie le contenu de `frontend/build/` dans le dossier `www/` de l'app (SFTP ou rsync avec l'utilisateur dédié créé par l'app). 3. Dans la config nginx avancée de l'app, ajoute le bloc `try_files` ci-dessus. YunoHost gère TLS, HSTS et le renouvellement des certificats. ## 6. Option D — Docker Le `Dockerfile` et `docker/nginx.conf` du dépôt (hérités du site Astro) servent déjà un site statique durci ; adapter le chemin de copie vers `frontend/build/` si tu veux cette voie. Utile pour l'infra OKI si tout le reste tourne déjà en conteneurs — sinon les options A/B sont plus simples. ## 7. Vérifier après mise en ligne - [ ] `curl -sI https://exemple.o-k-i.net | grep -i content-security` → CSP présente - [ ] La page `/outils` répond (et `/outils?cat=messagerie` filtre) - [ ] DevTools > Application > Service worker : enregistré ; passer hors-ligne et recharger une fiche déjà visitée → elle s'affiche - [ ] observatory.mozilla.org : note A/A+ attendue avec les en-têtes ci-dessus - [ ] Aucune requête sortante vers un domaine tiers (onglet Réseau)