fix: resolve production runtime issues #19

Merged
kevin merged 1 commits from fix/prod-runtime-issues into develop 2026-03-17 12:52:22 +00:00
5 changed files with 248 additions and 11 deletions

View File

@@ -37,7 +37,8 @@ export default defineNuxtConfig({
runtimeConfig: {
apiSecretKey: process.env.API_SECRET_KEY,
public: {
appVersion: getRepoVersion()
appVersion: getRepoVersion(),
apiKey: process.env.API_SECRET_KEY
}
},
vite: {

View File

@@ -4,8 +4,7 @@ import {
resolveFolderRemoteDir,
REMOTE_HOST,
} from "../utils/ssh.ts"
import {spawn} from "unenv/node/child_process";
import { spawn } from "node:child_process"
const isSafeFolder = (value: string) => /^[a-zA-Z0-9._-]+$/.test(value)

View File

@@ -4,7 +4,7 @@ import {
resolveFolderRemoteDir,
REMOTE_HOST,
} from "../utils/ssh.ts"
import {spawn} from "unenv/node/child_process";
import { spawn } from "node:child_process"
const isSafeFolder = (value: string) => /^[a-zA-Z0-9._-]+$/.test(value)
const isSafeFile = (value: string) => /^[a-zA-Z0-9._-]+$/.test(value)

View File

@@ -16,10 +16,12 @@ export default defineEventHandler((event) => {
return
}
const secureCookie = process.env.AUTH_COOKIE_SECURE === "true"
setCookie(event, "api_auth_token", expectedToken, {
httpOnly: true,
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
secure: secureCookie,
path: "/"
})
})

235
solution.md Normal file
View File

@@ -0,0 +1,235 @@
# Correctifs finaux de deploiement Supervisor
Ce document resume les correctifs finaux identifies pour faire fonctionner `Supervisor` en production sur `recette`.
## 1. Lancement en production
`Supervisor` n'est pas un site statique simple. Le projet contient :
- des routes serveur dans `server/api/*`
- des middlewares dans `server/middleware/*`
- un plugin serveur dans `server/plugins/metrics-worker.ts`
Il faut donc :
```bash
npm run build
node .output/server/index.mjs
```
En production, l'application a ete lancee via `pm2`.
## 2. Configuration Nginx
Le projet doit etre expose en reverse proxy vers le serveur Node sur `127.0.0.1:3000`.
Configuration minimale valide :
```nginx
server {
listen 80;
server_name supervisor.malio-dev.fr;
client_max_body_size 200M;
client_body_timeout 300s;
send_timeout 300s;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
### Pourquoi
- sans reverse proxy, les endpoints `/api/*` ne fonctionnent pas
- sans `client_max_body_size`, le speedtest d'upload retourne `413 Request Entity Too Large`
Apres modification :
```bash
nginx -t
systemctl reload nginx
```
## 3. Cookie d'authentification en HTTP
Le projet etait configure pour utiliser un cookie `Secure` en production, ce qui bloquait toutes les routes `/api/*` en HTTP avec des erreurs `401`.
Correctif applique dans `server/middleware/auth-cookie.ts` :
- le flag `secure` du cookie depend maintenant de `AUTH_COOKIE_SECURE`
Valeur a mettre en HTTP :
```env
AUTH_COOKIE_SECURE=false
```
Si un passage en HTTPS est fait plus tard :
```env
AUTH_COOKIE_SECURE=true
```
## 4. Variables d'environnement a utiliser
Exemple de `.env` fonctionnel :
```env
API_SECRET_KEY=...
DISCORD_BOT_TOKEN=...
DISCORD_CHANNEL_ID=...
BACKUPS_REMOTE_HOST=malio-b
BACKUPS_REMOTE_ROOT=/home/malio-b/backups
BACKUPS_MAX_FILES=200
DISK_COMMAND_LOCAL="cd /home/malio/Malio-ops/CheckStorage && bash check-storage.sh"
DISK_COMMAND_REMOTE="ssh malio-b \"cd /home/malio-b/Malio-ops/CheckStorage && bash check-storage.sh\""
BACKUP_SCRIPT_COMMAND_BACKUP_BDD_RECETTE="cd /home/malio/Malio-ops/RecetteScripts && bash backup-bdd-recette.sh"
BACKUP_SCRIPT_COMMAND_CHECK_STATUT_RECETTE="cd /home/malio/Malio-ops/RecetteScripts && bash check-statut-recette.sh"
BACKUP_SCRIPT_COMMAND_BACKUP_VAULTWARDEN="ssh bitwarden \"bash -lc 'cd /home/matt/vaultwarden/Malio-ops/BackupVaultWarden && ./backup-vaultwarden.sh'\""
BACKUPS_HOUR=19
AUTH_COOKIE_SECURE=false
```
### Important
Les commandes qui contiennent des espaces, `&&` ou des guillemets doivent etre entourees correctement dans le `.env`.
Le format suivant a provoque des erreurs lors d'un `source .env` :
```env
DISK_COMMAND_LOCAL=bash -lc '...'
```
Le shell l'interpretait comme une commande, pas comme une simple valeur.
## 5. PM2
Les variables ajoutees dans `.env` n'etaient pas toujours reprises par le process PM2 deja lance.
Sequence fiable :
```bash
cd /var/www/Supervisor
set -a
source .env
set +a
pm2 kill
pm2 start .output/server/index.mjs --name supervisor
pm2 save
```
Verification utile :
```bash
pm2 list
pm2 env 0 | grep DISK_COMMAND
```
## 6. Backups recette
Comme `Supervisor` tourne deja sur `ferme` / `recette`, les scripts de backup recette ne doivent pas repasser par `ssh ferme`.
Correct :
```env
BACKUP_SCRIPT_COMMAND_BACKUP_BDD_RECETTE="cd /home/malio/Malio-ops/RecetteScripts && bash backup-bdd-recette.sh"
BACKUP_SCRIPT_COMMAND_CHECK_STATUT_RECETTE="cd /home/malio/Malio-ops/RecetteScripts && bash check-statut-recette.sh"
```
La connexion SSH reste necessaire uniquement pour `vaultwarden`.
## 7. SSH vers vaultwarden
La commande distante utilisee est :
```env
BACKUP_SCRIPT_COMMAND_BACKUP_VAULTWARDEN="ssh bitwarden \"bash -lc 'cd /home/matt/vaultwarden/Malio-ops/BackupVaultWarden && ./backup-vaultwarden.sh'\""
```
Cela implique :
- une cle SSH disponible pour l'utilisateur qui lance `Supervisor`
- la cle publique autorisee sur `vault.lpc-liot.fr`
- une resolution correcte de l'alias `bitwarden` ou l'utilisation directe de `matt@vault.lpc-liot.fr`
Exemple de test :
```bash
ssh matt@vault.lpc-liot.fr "hostname"
```
## 8. Commandes disque
Les diagrammes de stockage dependent de :
- `DISK_COMMAND_LOCAL`
- `DISK_COMMAND_REMOTE`
Valeurs fonctionnelles :
```env
DISK_COMMAND_LOCAL="cd /home/malio/Malio-ops/CheckStorage && bash check-storage.sh"
DISK_COMMAND_REMOTE="ssh malio-b \"cd /home/malio-b/Malio-ops/CheckStorage && bash check-storage.sh\""
```
Le script local avait aussi un probleme de droits d'execution. Il a fallu le rendre executable.
Exemple :
```bash
chmod +x /home/malio/Malio-ops/CheckStorage/check-storage.sh
```
## 9. Commandes de verification utiles
Verifier le retour de l'API disque :
```bash
curl -s http://127.0.0.1:3000/api/disk -H "Authorization: Bearer <API_SECRET_KEY>"
```
Verifier le backup status :
```bash
curl -s http://127.0.0.1:3000/api/check-backup -H "Authorization: Bearer <API_SECRET_KEY>"
```
Verifier le process PM2 :
```bash
pm2 list
pm2 logs 0 --lines 100
```
Verifier la configuration Nginx chargee :
```bash
nginx -T
grep -R "supervisor.malio-dev.fr" /etc/nginx
```
## 10. Cause des principaux problemes rencontres
- erreurs `401` : cookie d'auth `Secure` alors que le site etait en HTTP
- erreurs `413` : absence de `client_max_body_size` dans le vhost Nginx
- `ssh undefined` : variable `BACKUPS_REMOTE_HOST` non prise en compte dans le process lance
- diagrammes vides : `DISK_COMMAND_LOCAL` et `DISK_COMMAND_REMOTE` absentes ou mal chargees
- commandes `.env` non lues correctement : quoting incorrect pour des commandes shell complexes
- stockage local vide : script local non executable
## 11. Point de securite
Des secrets ont ete affiches pendant le debug :
- `API_SECRET_KEY`
- `DISCORD_BOT_TOKEN`
Ils doivent etre consideres comme compromis et regeneres.