Rewrite DEPLOIEMENT.md to match actual codebase and stack
- Fix .env example: OPENAI_API_KEY → MISTRAL_API_KEY, SESSION_SECRET → SECRET_KEY, add ADMIN_SECRET - Remove manual DB init section (init_db() is automatic at service startup) - Fix build command: remove non-existent vite.config.selfhost.ts, use pnpm build - Rewrite env vars table: Mistral-first, add Redis/hCaptcha/flood/IP blacklist vars, fix FILTER_MODEL / SYNTHESIS_MODEL names - Remove Python code snippet in "Modèles IA" section (env vars suffice) - Clarify nginx.conf listens on 8080 (behind HAProxy) vs standalone (port 80) - Fix section 12: remove "décommentez le bloc HTTPS" (no such block in nginx.conf) - Fix dépannage: OpenAI → Mistral AI, correct API endpoint and curl command - Add VITE_* build-time var troubleshooting entry - Fix project structure: remove vite.config.selfhost.ts, add api-zod, update pages list - Fix pg_hba.conf: md5 → scram-sha-256 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+122
-104
@@ -1,5 +1,5 @@
|
|||||||
# Guide d'auto-hébergement — La Voix du Peuple
|
# Guide d'auto-hébergement — La Voix du Peuple
|
||||||
## RockyLinux 9 (ou RHEL 9, AlmaLinux 9)
|
## Rocky Linux 9 (ou RHEL 9, AlmaLinux 9)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -18,17 +18,20 @@ Internet
|
|||||||
- **Frontend** : React + Vite, servi comme fichiers statiques par Nginx
|
- **Frontend** : React + Vite, servi comme fichiers statiques par Nginx
|
||||||
- **Backend** : Flask + Gunicorn (4 workers), accessible uniquement via Nginx
|
- **Backend** : Flask + Gunicorn (4 workers), accessible uniquement via Nginx
|
||||||
- **Base de données** : PostgreSQL 15+
|
- **Base de données** : PostgreSQL 15+
|
||||||
- **IA** : Mistral AI (MISTRAL_API_KEY requis)
|
- **IA** : Mistral AI (`MISTRAL_API_KEY` requis) ou tout fournisseur compatible OpenAI
|
||||||
|
|
||||||
|
> **Note production :** En déploiement exposé à Internet, placer HAProxy devant Nginx pour la
|
||||||
|
> terminaison TLS. Voir `ARCHITECTURE.md` pour le schéma complet. Dans cette configuration,
|
||||||
|
> Nginx écoute sur le port 8080 (fichier `deploy/nginx.conf`) et HAProxy forward sur ce port.
|
||||||
|
> Pour un déploiement standalone sans HAProxy, changez `listen 8080;` en `listen 80;` dans
|
||||||
|
> `deploy/nginx.conf` et activez HTTPS avec certbot (section 12).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Prérequis
|
## Prérequis
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Mettre à jour le système
|
|
||||||
sudo dnf update -y
|
sudo dnf update -y
|
||||||
|
|
||||||
# Outils de base
|
|
||||||
sudo dnf install -y git curl wget epel-release
|
sudo dnf install -y git curl wget epel-release
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -73,21 +76,22 @@ sudo systemctl enable nginx
|
|||||||
## 2. Configurer PostgreSQL
|
## 2. Configurer PostgreSQL
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Connexion en tant que postgres
|
|
||||||
sudo -u postgres psql
|
sudo -u postgres psql
|
||||||
|
```
|
||||||
|
|
||||||
-- Dans psql :
|
Dans psql :
|
||||||
|
```sql
|
||||||
CREATE USER voixdupeuple WITH PASSWORD 'CHANGEME_MOT_DE_PASSE_FORT';
|
CREATE USER voixdupeuple WITH PASSWORD 'CHANGEME_MOT_DE_PASSE_FORT';
|
||||||
CREATE DATABASE voixdupeuple OWNER voixdupeuple;
|
CREATE DATABASE voixdupeuple OWNER voixdupeuple;
|
||||||
GRANT ALL PRIVILEGES ON DATABASE voixdupeuple TO voixdupeuple;
|
GRANT ALL PRIVILEGES ON DATABASE voixdupeuple TO voixdupeuple;
|
||||||
\q
|
\q
|
||||||
```
|
```
|
||||||
|
|
||||||
Éditez `/var/lib/pgsql/15/data/pg_hba.conf` pour autoriser la connexion locale par mot de passe :
|
Éditez `/var/lib/pgsql/15/data/pg_hba.conf` — remplacez `ident` par `scram-sha-256` sur
|
||||||
|
la ligne `127.0.0.1/32` :
|
||||||
|
|
||||||
```
|
```
|
||||||
# Remplacez "ident" par "md5" sur la ligne 127.0.0.1/32 :
|
host all all 127.0.0.1/32 scram-sha-256
|
||||||
host all all 127.0.0.1/32 md5
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -109,13 +113,12 @@ sudo chown voixdupeuple:voixdupeuple /opt/voix-du-peuple
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. Cloner le dépôt depuis Gitea
|
## 4. Cloner le dépôt
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo -u voixdupeuple bash -c "
|
sudo -u voixdupeuple git clone \
|
||||||
cd /opt
|
https://votre-depot.example.com/voix-du-peuple.git \
|
||||||
git clone https://votre-gitea.example.com/utilisateur/voix-du-peuple.git voix-du-peuple
|
/opt/voix-du-peuple
|
||||||
"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -123,27 +126,24 @@ sudo -u voixdupeuple bash -c "
|
|||||||
## 5. Configurer les variables d'environnement
|
## 5. Configurer les variables d'environnement
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo -u voixdupeuple bash -c "
|
sudo -u voixdupeuple cp /opt/voix-du-peuple/.env.example /opt/voix-du-peuple/.env
|
||||||
cp /opt/voix-du-peuple/.env.example /opt/voix-du-peuple/.env
|
|
||||||
"
|
|
||||||
|
|
||||||
# Éditer le fichier .env
|
|
||||||
sudo nano /opt/voix-du-peuple/.env
|
sudo nano /opt/voix-du-peuple/.env
|
||||||
```
|
```
|
||||||
|
|
||||||
Remplissez au minimum :
|
Valeurs obligatoires à renseigner :
|
||||||
|
|
||||||
```env
|
```env
|
||||||
|
# Base de données
|
||||||
DATABASE_URL=postgresql://voixdupeuple:CHANGEME_MOT_DE_PASSE_FORT@127.0.0.1:5432/voixdupeuple
|
DATABASE_URL=postgresql://voixdupeuple:CHANGEME_MOT_DE_PASSE_FORT@127.0.0.1:5432/voixdupeuple
|
||||||
OPENAI_API_KEY=sk-VOTRE_CLE_OPENAI
|
|
||||||
SESSION_SECRET=GENEREZ_UNE_VALEUR_ALEATOIRE_ICI
|
|
||||||
PORT=8000
|
|
||||||
FLASK_ENV=production
|
|
||||||
```
|
|
||||||
|
|
||||||
Générez le `SESSION_SECRET` :
|
# IA — Mistral AI (recommandé)
|
||||||
```bash
|
MISTRAL_API_KEY=votre-cle-mistral
|
||||||
python3.11 -c "import secrets; print(secrets.token_hex(32))"
|
|
||||||
|
# Sécurité — générez avec : python3 -c "import secrets; print(secrets.token_hex(32))"
|
||||||
|
SECRET_KEY=VALEUR_ALEATOIRE_LONGUE
|
||||||
|
|
||||||
|
# Panel d'administration
|
||||||
|
ADMIN_SECRET=MOT_DE_PASSE_ADMIN_FORT
|
||||||
```
|
```
|
||||||
|
|
||||||
Sécurisez le fichier :
|
Sécurisez le fichier :
|
||||||
@@ -169,18 +169,9 @@ sudo -u voixdupeuple bash -c "
|
|||||||
|
|
||||||
## 7. Initialiser la base de données
|
## 7. Initialiser la base de données
|
||||||
|
|
||||||
```bash
|
La base de données est initialisée **automatiquement** au premier démarrage du service
|
||||||
sudo -u voixdupeuple bash -c "
|
(création des tables et migrations incrémentales idempotentes). Aucune action manuelle n'est
|
||||||
cd /opt/voix-du-peuple/artifacts/flask-api
|
requise. Passez directement à l'étape suivante.
|
||||||
source /opt/voix-du-peuple/.env
|
|
||||||
export DATABASE_URL OPENAI_API_KEY SESSION_SECRET FLASK_ENV PORT
|
|
||||||
/opt/voix-du-peuple/.venv/bin/python3 -c '
|
|
||||||
from database import init_db
|
|
||||||
init_db()
|
|
||||||
print(\"Base de données initialisée.\")
|
|
||||||
'
|
|
||||||
"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -190,14 +181,17 @@ print(\"Base de données initialisée.\")
|
|||||||
sudo -u voixdupeuple bash -c "
|
sudo -u voixdupeuple bash -c "
|
||||||
cd /opt/voix-du-peuple
|
cd /opt/voix-du-peuple
|
||||||
pnpm install --frozen-lockfile
|
pnpm install --frozen-lockfile
|
||||||
|
|
||||||
cd artifacts/voix-du-peuple
|
cd artifacts/voix-du-peuple
|
||||||
pnpm exec vite build --config vite.config.selfhost.ts
|
pnpm build
|
||||||
"
|
"
|
||||||
```
|
```
|
||||||
|
|
||||||
Les fichiers statiques sont générés dans `artifacts/voix-du-peuple/dist/public/`.
|
Les fichiers statiques sont générés dans `artifacts/voix-du-peuple/dist/public/`.
|
||||||
|
|
||||||
|
Si vous avez configuré `VITE_APP_URL` (URL publique du site, pour le QR code du flyer) ou
|
||||||
|
`VITE_HCAPTCHA_SITE_KEY`, ajoutez ces variables dans le `.env` **avant** le build — elles
|
||||||
|
sont intégrées statiquement dans le bundle.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. Configurer le service systemd (Gunicorn)
|
## 9. Configurer le service systemd (Gunicorn)
|
||||||
@@ -229,14 +223,16 @@ curl http://127.0.0.1:8000/api/healthz
|
|||||||
|
|
||||||
## 10. Configurer Nginx
|
## 10. Configurer Nginx
|
||||||
|
|
||||||
|
Le fichier `deploy/nginx.conf` configure Nginx en écoute sur le port **8080** (mode
|
||||||
|
derrière HAProxy). Pour un déploiement standalone sans HAProxy, changez `listen 8080;`
|
||||||
|
en `listen 80;` avant de copier.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Copier la config Nginx
|
|
||||||
sudo cp /opt/voix-du-peuple/deploy/nginx.conf \
|
sudo cp /opt/voix-du-peuple/deploy/nginx.conf \
|
||||||
/etc/nginx/conf.d/voix-du-peuple.conf
|
/etc/nginx/conf.d/voix-du-peuple.conf
|
||||||
|
|
||||||
# Éditez le fichier pour mettre votre nom de domaine
|
# Si déploiement standalone : changer le port d'écoute
|
||||||
sudo nano /etc/nginx/conf.d/voix-du-peuple.conf
|
sudo sed -i 's/listen 8080;/listen 80;/' /etc/nginx/conf.d/voix-du-peuple.conf
|
||||||
# Remplacez voix-du-peuple.example.com par votre domaine
|
|
||||||
|
|
||||||
# Tester la configuration
|
# Tester la configuration
|
||||||
sudo nginx -t
|
sudo nginx -t
|
||||||
@@ -250,32 +246,35 @@ sudo systemctl reload nginx
|
|||||||
## 11. Ouvrir le pare-feu
|
## 11. Ouvrir le pare-feu
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# Standalone (Nginx expose directement HTTP/HTTPS)
|
||||||
sudo firewall-cmd --permanent --add-service=http
|
sudo firewall-cmd --permanent --add-service=http
|
||||||
sudo firewall-cmd --permanent --add-service=https
|
sudo firewall-cmd --permanent --add-service=https
|
||||||
sudo firewall-cmd --reload
|
sudo firewall-cmd --reload
|
||||||
```
|
```
|
||||||
|
|
||||||
SELinux — autoriser Nginx à se connecter à Gunicorn :
|
SELinux — autoriser Nginx à proxyfier vers Gunicorn :
|
||||||
```bash
|
```bash
|
||||||
sudo setsebool -P httpd_can_network_connect 1
|
sudo setsebool -P httpd_can_network_connect 1
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 12. (Recommandé) HTTPS avec Let's Encrypt
|
## 12. (Recommandé) HTTPS avec Let's Encrypt — déploiement standalone
|
||||||
|
|
||||||
|
> Ne s'applique qu'en déploiement standalone (Nginx exposé directement). Si HAProxy gère
|
||||||
|
> le TLS, configurez Let's Encrypt sur HAProxy — voir `ARCHITECTURE.md`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo dnf install -y certbot python3-certbot-nginx
|
sudo dnf install -y certbot python3-certbot-nginx
|
||||||
|
|
||||||
|
# Remplacez voix-du-peuple.example.com par votre domaine
|
||||||
sudo certbot --nginx -d voix-du-peuple.example.com \
|
sudo certbot --nginx -d voix-du-peuple.example.com \
|
||||||
--email admin@example.com --agree-tos --no-eff-email
|
--email contact@example.com --agree-tos --no-eff-email
|
||||||
|
|
||||||
# Renouvellement automatique (déjà configuré par certbot)
|
# Vérifier le renouvellement automatique
|
||||||
sudo systemctl status certbot-renew.timer
|
sudo systemctl status certbot-renew.timer
|
||||||
```
|
```
|
||||||
|
|
||||||
Puis décommentez le bloc HTTPS dans `/etc/nginx/conf.d/voix-du-peuple.conf`.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Structure du projet
|
## Structure du projet
|
||||||
@@ -284,26 +283,29 @@ Puis décommentez le bloc HTTPS dans `/etc/nginx/conf.d/voix-du-peuple.conf`.
|
|||||||
voix-du-peuple/
|
voix-du-peuple/
|
||||||
├── artifacts/
|
├── artifacts/
|
||||||
│ ├── flask-api/ # Backend Python Flask
|
│ ├── flask-api/ # Backend Python Flask
|
||||||
│ │ ├── app.py # Application principale + routes
|
│ │ ├── app.py # Application principale + routes API
|
||||||
│ │ ├── ai_agent.py # Agent IA (filtrage + synthèse)
|
│ │ ├── ai_agent.py # Agent IA (filtrage, synthèse, check-law)
|
||||||
│ │ ├── legal_framework.py # Prompts ancrés dans le droit international
|
│ │ ├── legal_framework.py # Prompts ancrés dans le droit (16 sources)
|
||||||
│ │ ├── database.py # Accès PostgreSQL (psycopg2)
|
│ │ ├── database.py # Accès PostgreSQL (psycopg2, sans ORM)
|
||||||
│ │ ├── requirements.txt # Dépendances Python
|
│ │ ├── requirements.txt # Dépendances Python
|
||||||
│ │ └── start.sh # Démarrage développement
|
│ │ └── start.sh # Démarrage dev direct (python app.py)
|
||||||
│ └── voix-du-peuple/ # Frontend React + Vite
|
│ └── voix-du-peuple/ # Frontend React + Vite 7
|
||||||
│ ├── src/
|
│ ├── src/
|
||||||
│ │ ├── pages/ # home.tsx, about.tsx
|
│ │ ├── pages/ # home, about, transparence, contributions-brutes,
|
||||||
│ │ ├── components/ # Composants UI (shadcn/ui + radix)
|
│ │ │ # consultations, legal-notice, privacy-policy, admin…
|
||||||
│ │ └── App.tsx # Routing principal
|
│ │ ├── components/ # UI (shadcn/ui + Radix), consent-dialog, navbar…
|
||||||
│ └── vite.config.ts # Config Vite (développement + production)
|
│ │ ├── lib/ # prompts.ts (verbatim IA), hooks, utils
|
||||||
|
│ │ └── App.tsx # Routing principal (Wouter)
|
||||||
|
│ └── vite.config.ts # Config Vite (dev + production)
|
||||||
├── lib/
|
├── lib/
|
||||||
│ ├── api-spec/ # Spécification OpenAPI
|
│ ├── api-spec/ # Spécification OpenAPI + config Orval
|
||||||
│ ├── api-client-react/ # Hooks React Query générés
|
│ ├── api-client-react/ # Hooks React Query générés
|
||||||
│ └── db/ # Schéma Drizzle (référence)
|
│ └── api-zod/ # Schémas Zod générés
|
||||||
├── deploy/
|
├── deploy/
|
||||||
│ ├── voix-du-peuple-api.service # Service systemd Gunicorn
|
│ ├── voix-du-peuple-api.service # Service systemd Gunicorn
|
||||||
│ └── nginx.conf # Configuration Nginx
|
│ └── nginx.conf # Configuration Nginx (port 8080, derrière HAProxy)
|
||||||
├── .env.example # Variables d'environnement (modèle)
|
├── docs/ # Documentation technique (RGPD, sécurité, prompts…)
|
||||||
|
├── .env.example # Variables d'environnement (modèle commenté)
|
||||||
└── DEPLOIEMENT.md # Ce fichier
|
└── DEPLOIEMENT.md # Ce fichier
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -313,32 +315,36 @@ voix-du-peuple/
|
|||||||
|
|
||||||
| Variable | Obligatoire | Description |
|
| Variable | Obligatoire | Description |
|
||||||
|----------|-------------|-------------|
|
|----------|-------------|-------------|
|
||||||
| `DATABASE_URL` | Oui | URL PostgreSQL complète |
|
| `DATABASE_URL` | Oui | URL PostgreSQL — `postgresql://user:pass@host:5432/db` |
|
||||||
| `OPENAI_API_KEY` | Oui | Clé API OpenAI (sk-...) |
|
| `MISTRAL_API_KEY` | Oui* | Clé API Mistral AI (fournisseur par défaut) |
|
||||||
| `OPENAI_BASE_URL` | Non | Proxy OpenAI compatible (Ollama, Azure, etc.) |
|
| `OPENAI_API_KEY` | Oui* | Alternative si Mistral non utilisé (compatible OpenAI) |
|
||||||
| `OPENAI_FILTER_MODEL` | Non | Modèle de filtrage (défaut : `gpt-4o-mini`) |
|
| `OPENAI_BASE_URL` | Non | Base URL pour fournisseur tiers (Ollama, proxy…) |
|
||||||
| `OPENAI_SYNTHESIS_MODEL` | Non | Modèle de synthèse (défaut : `gpt-4o`) |
|
| `FILTER_MODEL` | Non | Modèle de filtrage (défaut : `mistral-small-latest`) |
|
||||||
| `SESSION_SECRET` | Oui | Clé secrète Flask (min 32 caractères aléatoires) |
|
| `SYNTHESIS_MODEL` | Non | Modèle de synthèse (défaut : `mistral-large-latest`) |
|
||||||
| `PORT` | Non | Port Gunicorn (défaut : 8000) |
|
| `SECRET_KEY` | Recommandé | Active le cooldown cookie et le consentement RGPD signé HMAC-SHA256 |
|
||||||
| `FLASK_ENV` | Non | `production` ou `development` |
|
| `ADMIN_SECRET` | Recommandé | Mot de passe Bearer token pour le panel `/admin` |
|
||||||
|
| `REDIS_URL` | Non | Rate limiting persistant entre workers — `redis://localhost:6379/0` |
|
||||||
|
| `RATE_LIMIT_CONTRIBUTIONS` | Non | Seuil de soumissions (défaut : `5 per minute;3 per hour`) |
|
||||||
|
| `CONTRIBUTION_COOLDOWN_SECONDS` | Non | Délai inter-soumissions par session (défaut : `240`) |
|
||||||
|
| `FLOOD_THRESHOLD` | Non | Seuil d'alerte flood en 5 min (défaut : `10`) |
|
||||||
|
| `IP_BLACKLIST_DAYS` | Non | Durée du blacklist IP (défaut : `30`) |
|
||||||
|
| `HCAPTCHA_SECRET_KEY` | Non | Active la vérification hCaptcha côté serveur |
|
||||||
|
| `VITE_HCAPTCHA_SITE_KEY` | Non | Clé publique hCaptcha côté frontend (rebuild requis) |
|
||||||
|
| `VITE_APP_URL` | Non | URL publique du site — utilisée par le QR code du flyer (rebuild requis) |
|
||||||
|
|
||||||
|
*`MISTRAL_API_KEY` est prioritaire. Si absent, `OPENAI_API_KEY` est utilisé. L'un des deux est obligatoire.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Modèles IA utilisés
|
## Modèles IA
|
||||||
|
|
||||||
| Fonction | Modèle par défaut | Variable d'environnement |
|
| Rôle | Modèle par défaut | Variable de contrôle |
|
||||||
|----------|-------------------|--------------------------|
|
|------|-------------------|----------------------|
|
||||||
| Filtrage des idées | `mistral-small-latest` | `FILTER_MODEL` |
|
| Filtrage des contributions | `mistral-small-latest` | `FILTER_MODEL` |
|
||||||
| Synthèse collective | `mistral-large-latest` | `SYNTHESIS_MODEL` |
|
| Synthèse collective | `mistral-large-latest` | `SYNTHESIS_MODEL` |
|
||||||
|
| Vérification cadre légal | même que `FILTER_MODEL` | `FILTER_MODEL` |
|
||||||
|
|
||||||
Pour changer les modèles, éditez `artifacts/flask-api/ai_agent.py` :
|
Pour changer de modèle, définissez la variable dans `.env` — aucune modification du code n'est nécessaire.
|
||||||
```python
|
|
||||||
# Filtrage (ligne ~56)
|
|
||||||
model="gpt-4o-mini", # ou tout modèle OpenAI compatible
|
|
||||||
|
|
||||||
# Synthèse (ligne ~104)
|
|
||||||
model="gpt-4o", # ou tout modèle OpenAI compatible
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -349,16 +355,15 @@ sudo -u voixdupeuple bash -c "
|
|||||||
cd /opt/voix-du-peuple
|
cd /opt/voix-du-peuple
|
||||||
git pull origin main
|
git pull origin main
|
||||||
|
|
||||||
# Mise à jour des dépendances Python si nécessaire
|
# Dépendances Python
|
||||||
.venv/bin/pip install -r artifacts/flask-api/requirements.txt
|
.venv/bin/pip install -r artifacts/flask-api/requirements.txt
|
||||||
|
|
||||||
# Mise à jour des dépendances Node et rebuild frontend
|
# Rebuild frontend
|
||||||
pnpm install --frozen-lockfile
|
pnpm install --frozen-lockfile
|
||||||
cd artifacts/voix-du-peuple
|
cd artifacts/voix-du-peuple && pnpm build
|
||||||
pnpm exec vite build --config vite.config.selfhost.ts
|
|
||||||
"
|
"
|
||||||
|
|
||||||
# Redémarrer le service
|
# Redémarrer le service (les migrations DB s'appliquent automatiquement)
|
||||||
sudo systemctl restart voix-du-peuple-api
|
sudo systemctl restart voix-du-peuple-api
|
||||||
sudo systemctl reload nginx
|
sudo systemctl reload nginx
|
||||||
```
|
```
|
||||||
@@ -368,10 +373,10 @@ sudo systemctl reload nginx
|
|||||||
## Logs et supervision
|
## Logs et supervision
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Logs API Flask
|
# Logs API Flask (journald + fichiers)
|
||||||
sudo journalctl -u voix-du-peuple-api -f
|
sudo journalctl -u voix-du-peuple-api -f
|
||||||
tail -f /var/log/voix-du-peuple/api-error.log
|
sudo tail -f /var/log/voix-du-peuple/api-error.log
|
||||||
tail -f /var/log/voix-du-peuple/api-access.log
|
sudo tail -f /var/log/voix-du-peuple/api-access.log
|
||||||
|
|
||||||
# Logs Nginx
|
# Logs Nginx
|
||||||
sudo tail -f /var/log/nginx/error.log
|
sudo tail -f /var/log/nginx/error.log
|
||||||
@@ -391,31 +396,44 @@ sudo systemctl status postgresql-15
|
|||||||
```bash
|
```bash
|
||||||
# Vérifier que Gunicorn tourne
|
# Vérifier que Gunicorn tourne
|
||||||
sudo systemctl status voix-du-peuple-api
|
sudo systemctl status voix-du-peuple-api
|
||||||
|
|
||||||
# Vérifier SELinux
|
# Vérifier SELinux
|
||||||
sudo setsebool -P httpd_can_network_connect 1
|
sudo setsebool -P httpd_can_network_connect 1
|
||||||
|
|
||||||
|
# Tester Gunicorn directement
|
||||||
|
curl http://127.0.0.1:8000/api/healthz
|
||||||
```
|
```
|
||||||
|
|
||||||
### Erreur "could not connect to server" (PostgreSQL)
|
### Erreur "could not connect to server" (PostgreSQL)
|
||||||
```bash
|
```bash
|
||||||
# Vérifier que PostgreSQL tourne
|
|
||||||
sudo systemctl status postgresql-15
|
sudo systemctl status postgresql-15
|
||||||
# Vérifier l'URL de connexion dans .env
|
psql -U voixdupeuple -h 127.0.0.1 -d voixdupeuple -c "\dt"
|
||||||
psql -U voixdupeuple -h 127.0.0.1 -d voixdupeuple
|
# Vérifier DATABASE_URL dans .env
|
||||||
```
|
```
|
||||||
|
|
||||||
### Erreur OpenAI API
|
### Erreur Mistral AI API
|
||||||
```bash
|
```bash
|
||||||
# Vérifier la clé dans .env
|
# Vérifier la clé dans .env
|
||||||
grep OPENAI_API_KEY /opt/voix-du-peuple/.env
|
grep MISTRAL_API_KEY /opt/voix-du-peuple/.env
|
||||||
# Tester directement
|
|
||||||
curl https://api.openai.com/v1/models \
|
# Tester l'accès à l'API Mistral
|
||||||
-H "Authorization: Bearer $OPENAI_API_KEY"
|
curl https://api.mistral.ai/v1/models \
|
||||||
|
-H "Authorization: Bearer $(grep MISTRAL_API_KEY /opt/voix-du-peuple/.env | cut -d= -f2)"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Le frontend affiche une page blanche
|
### Le frontend affiche une page blanche
|
||||||
```bash
|
```bash
|
||||||
# Vérifier que le build existe
|
# Vérifier que le build existe
|
||||||
ls /opt/voix-du-peuple/artifacts/voix-du-peuple/dist/public/
|
ls /opt/voix-du-peuple/artifacts/voix-du-peuple/dist/public/
|
||||||
|
|
||||||
# Vérifier les droits
|
# Vérifier les droits
|
||||||
sudo chown -R voixdupeuple:voixdupeuple /opt/voix-du-peuple/artifacts/voix-du-peuple/dist/
|
sudo chown -R voixdupeuple:voixdupeuple \
|
||||||
|
/opt/voix-du-peuple/artifacts/voix-du-peuple/dist/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Les variables VITE_* ne sont pas prises en compte
|
||||||
|
Les variables préfixées `VITE_` sont intégrées au moment du build, pas à l'exécution.
|
||||||
|
Après toute modification de `VITE_APP_URL` ou `VITE_HCAPTCHA_SITE_KEY`, relancez le build :
|
||||||
|
```bash
|
||||||
|
cd /opt/voix-du-peuple/artifacts/voix-du-peuple && pnpm build
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user