Files
la-voix-du-peuple/docs/INSTALL_ROCKY.md
T
pironantoine 57211ad393 Add secure admin panel and documentation updates
Add secure admin panel with authentication and authorization features, update DEX.md to include admin panel documentation, and modify INSTALL_ROCKY.md to include ADMIN_SECRET configuration.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 923ae0e3-a363-4db8-b04a-e8baca2a1330
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 79c67b0b-a0eb-4a65-acef-813c12178ea4
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8af7d2ec-2cc3-4ece-8af3-9f071488d072/923ae0e3-a363-4db8-b04a-e8baca2a1330/sVU8w5x
Replit-Helium-Checkpoint-Created: true
2026-04-05 03:45:47 +00:00

543 lines
12 KiB
Markdown

# Installation sur RockyLinux — La Voix du Peuple
**Cible** : VM RockyLinux 9.x
**Port public** : HTTP 8080 (vous gérez le HTTPS en amont)
**Port interne** : Gunicorn 8000 (localhost uniquement)
**Répertoire d'installation** : `/opt/voix-du-peuple`
**Utilisateur système** : `voixdupeuple`
---
## Table des matières
1. [Prérequis](#1-prérequis)
2. [Préparation du serveur](#2-préparation-du-serveur)
3. [Installation des paquets](#3-installation-des-paquets)
4. [Utilisateur système](#4-utilisateur-système)
5. [Clonage du dépôt](#5-clonage-du-dépôt)
6. [Base de données PostgreSQL](#6-base-de-données-postgresql)
7. [Environnement Python](#7-environnement-python)
8. [Configuration du domaine et variables d'environnement](#8-configuration-du-domaine-et-variables-denvironnement)
9. [Build du frontend](#9-build-du-frontend)
10. [Service Gunicorn (systemd)](#10-service-gunicorn-systemd)
11. [Nginx](#11-nginx)
12. [Firewall](#12-firewall)
13. [Vérification finale](#13-vérification-finale)
14. [Disaster Recovery](#14-disaster-recovery)
15. [Maintenance et mises à jour](#15-maintenance-et-mises-à-jour)
---
## 1. Prérequis
- VM RockyLinux 9.x avec accès root (ou sudo)
- 1 vCPU minimum, 1 Go RAM (2 Go recommandés)
- 10 Go de disque
- Accès réseau sortant (pour cloner le dépôt et télécharger les paquets)
- Nom de domaine configuré (enregistrement DNS A pointant vers l'IP de la VM)
- Clé SSH ou accès console
---
## 2. Préparation du serveur
```bash
# Mise à jour complète du système
dnf update -y
# Outils de base
dnf install -y curl wget git tar unzip vim
# Activer le dépôt EPEL (nécessaire pour certains paquets)
dnf install -y epel-release
```
---
## 3. Installation des paquets
### Python 3.11
```bash
dnf install -y python3.11 python3.11-pip python3.11-devel
python3.11 --version # doit afficher 3.11.x
```
### Node.js 20 et pnpm
```bash
# Dépôt Node.js 20 LTS
curl -fsSL https://rpm.nodesource.com/setup_20.x | bash -
dnf install -y nodejs
# pnpm
npm install -g pnpm
pnpm --version
node --version # doit afficher 20.x
```
### PostgreSQL 15
```bash
# Dépôt officiel PostgreSQL
dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
dnf -qy module disable postgresql
dnf install -y postgresql15-server postgresql15
# Initialisation et démarrage
postgresql-15-setup initdb
systemctl enable postgresql-15
systemctl start postgresql-15
systemctl status postgresql-15 # doit afficher "active (running)"
```
### Nginx
```bash
dnf install -y nginx
systemctl enable nginx
```
---
## 4. Utilisateur système
```bash
# Créer un utilisateur dédié sans shell de connexion
useradd -r -s /sbin/nologin -d /opt/voix-du-peuple voixdupeuple
# Répertoire de logs
mkdir -p /var/log/voix-du-peuple
chown voixdupeuple:voixdupeuple /var/log/voix-du-peuple
```
---
## 5. Clonage du dépôt
```bash
# Créer le répertoire d'installation
mkdir -p /opt/voix-du-peuple
cd /opt/voix-du-peuple
# Cloner depuis votre Gitea
git clone https://homegit.gyozamancave.fr/billisdead/la-voix-du-peuple.git .
# (ou via SSH si une clé est configurée sur votre serveur Gitea)
# Rendre le répertoire accessible à l'utilisateur système
chown -R voixdupeuple:voixdupeuple /opt/voix-du-peuple
```
---
## 6. Base de données PostgreSQL
```bash
# Se connecter en tant que postgres
su - postgres
# Créer l'utilisateur et la base
psql <<EOF
CREATE USER voix_user WITH PASSWORD 'MOT_DE_PASSE_FORT';
CREATE DATABASE voix_du_peuple OWNER voix_user;
GRANT ALL PRIVILEGES ON DATABASE voix_du_peuple TO voix_user;
EOF
exit # revenir à root
```
Tester la connexion :
```bash
psql -U voix_user -d voix_du_peuple -h 127.0.0.1 -c '\l'
```
---
## 7. Environnement Python
```bash
cd /opt/voix-du-peuple
# Créer le virtualenv
python3.11 -m venv .venv
# Installer les dépendances
.venv/bin/pip install --upgrade pip
.venv/bin/pip install -r artifacts/flask-api/requirements.txt
```
---
## 8. Configuration du domaine et variables d'environnement
### 8.1 Créer le fichier `.env`
```bash
cp .env.example .env # si le fichier exemple existe, sinon créer manuellement
vim .env
```
Contenu minimal du `.env` :
```bash
# Base de données
DATABASE_URL=postgresql://voix_user:MOT_DE_PASSE_FORT@127.0.0.1:5432/voix_du_peuple
# IA Mistral
MISTRAL_API_KEY=votre_cle_mistral_ici
# Sécurité Flask
SESSION_SECRET=generez-une-chaine-aleatoire-longue-ici
# Panel admin — mot de passe de connexion à /admin (OBLIGATOIRE)
ADMIN_SECRET=choisissez-un-mot-de-passe-long-et-complexe-ici
# Modèles IA (valeurs par défaut si omis)
# FILTER_MODEL=mistral-small-latest
# SYNTHESIS_MODEL=mistral-large-latest
# Domaine public — utilisé par le QR code du flyer
VITE_APP_URL=https://votredomaine.fr
```
Générer `SESSION_SECRET` et `ADMIN_SECRET` :
```bash
python3 -c "import secrets; print(secrets.token_hex(32))"
# Exécuter deux fois pour obtenir deux valeurs distinctes
```
### 8.2 Changer le domaine (QR code)
Le flyer génère automatiquement son QR code à partir de `VITE_APP_URL`. Pour changer le domaine :
```bash
# Depuis /opt/voix-du-peuple
bash scripts/set-domain.sh https://votredomaine.fr
```
Ce script met à jour `VITE_APP_URL` dans `.env` et reconstruit le frontend.
Appliquer ensuite : `systemctl reload nginx`
---
## 9. Build du frontend
```bash
cd /opt/voix-du-peuple
# Installer les dépendances Node
pnpm install
# Construire le frontend (lit VITE_APP_URL depuis .env)
source .env
export VITE_APP_URL
pnpm --filter @workspace/voix-du-peuple run build --config vite.config.selfhost.ts
# Vérifier que le build est présent
ls artifacts/voix-du-peuple/dist/public/
```
---
## 10. Service Gunicorn (systemd)
```bash
# Copier le fichier de service
cp deploy/voix-du-peuple-api.service /etc/systemd/system/
# Recharger systemd et activer le service
systemctl daemon-reload
systemctl enable voix-du-peuple-api
systemctl start voix-du-peuple-api
systemctl status voix-du-peuple-api
```
Vérifier que Gunicorn écoute bien sur le port interne :
```bash
ss -tlnp | grep 8000
# doit afficher : 127.0.0.1:8000
```
Tester l'API directement :
```bash
curl http://127.0.0.1:8000/health
# réponse attendue : {"status": "ok"}
```
---
## 11. Nginx
### 11.1 Installer la configuration
```bash
# Copier la config fournie
cp deploy/nginx.conf /etc/nginx/conf.d/voix-du-peuple.conf
# (Optionnel) Ajuster le nom de serveur dans la config
vim /etc/nginx/conf.d/voix-du-peuple.conf
# Modifier : server_name _;
# En : server_name votredomaine.fr;
# Tester la configuration
nginx -t
# Démarrer Nginx
systemctl start nginx
systemctl status nginx
```
### 11.2 Vérifier que Nginx écoute sur 8080
```bash
ss -tlnp | grep 8080
# doit afficher : 0.0.0.0:8080
```
---
## 12. Firewall
```bash
# Autoriser le port 8080 (HTTP)
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload
# Vérifier
firewall-cmd --list-ports
```
> Le port 8000 (Gunicorn) ne doit PAS être ouvert — il n'est accessible que depuis localhost via Nginx.
---
## 13. Vérification finale
```bash
# Health check API (via Nginx)
curl http://localhost:8080/health
# {"status": "ok"}
# Page principale
curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/
# 200
# Depuis l'extérieur (remplacer par l'IP de votre VM)
curl http://IP_DE_LA_VM:8080/health
```
**Checklist** :
- [ ] `systemctl status postgresql-15` → active
- [ ] `systemctl status voix-du-peuple-api` → active
- [ ] `systemctl status nginx` → active
- [ ] `curl http://localhost:8080/health``{"status":"ok"}`
- [ ] L'interface s'affiche dans le navigateur sur `http://IP:8080`
- [ ] Le flyer `/flyer` affiche le bon nom de domaine dans le QR code
---
## 14. Disaster Recovery
### 14.1 Sauvegarde de la base de données
```bash
# Dump complet (à planifier via cron)
pg_dump -U voix_user -h 127.0.0.1 voix_du_peuple > /opt/backups/voix_$(date +%Y%m%d_%H%M).sql
# Automatiser avec cron (tous les jours à 3h)
crontab -e
# Ajouter :
# 0 3 * * * pg_dump -U voix_user -h 127.0.0.1 voix_du_peuple > /opt/backups/voix_$(date +\%Y\%m\%d).sql
```
```bash
mkdir -p /opt/backups
```
### 14.2 Restauration de la base de données
```bash
# Stopper l'API pendant la restauration
systemctl stop voix-du-peuple-api
# Vider et restaurer la base
psql -U voix_user -h 127.0.0.1 voix_du_peuple -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
psql -U voix_user -h 127.0.0.1 voix_du_peuple < /opt/backups/voix_20260401.sql
# Redémarrer
systemctl start voix-du-peuple-api
```
### 14.3 Réinstallation complète depuis zéro
Si la VM est perdue, répéter les étapes 1 à 13 puis restaurer la base depuis le dernier backup :
```bash
psql -U voix_user -h 127.0.0.1 voix_du_peuple < /opt/backups/voix_DERNIER.sql
```
Les backups doivent être stockés **hors de la VM** (NFS, S3, objet distant…).
### 14.4 Rollback de code
```bash
cd /opt/voix-du-peuple
# Voir l'historique des commits
git log --oneline -10
# Revenir à un commit précédent
git checkout <COMMIT_HASH>
# Reconstruire le frontend si nécessaire
bash scripts/set-domain.sh https://votredomaine.fr
# Redémarrer l'API
systemctl restart voix-du-peuple-api
systemctl reload nginx
```
### 14.5 En cas de service hors ligne
```bash
# Diagnostic rapide
systemctl status voix-du-peuple-api
journalctl -u voix-du-peuple-api -n 50
systemctl status nginx
journalctl -u nginx -n 20
systemctl status postgresql-15
# Relance forcée
systemctl restart voix-du-peuple-api
systemctl restart nginx
```
---
## 15. Maintenance et mises à jour
### 15.1 Mise à jour du code
```bash
cd /opt/voix-du-peuple
# Récupérer les derniers commits depuis Gitea
git pull origin main
# Si les dépendances Python ont changé (requirements.txt modifié)
.venv/bin/pip install -r artifacts/flask-api/requirements.txt
# Si les dépendances Node ont changé (package.json modifié)
pnpm install
# Reconstruire le frontend (toujours faire après un pull)
source .env && export VITE_APP_URL
pnpm --filter @workspace/voix-du-peuple run build --config vite.config.selfhost.ts
# Appliquer
systemctl restart voix-du-peuple-api
systemctl reload nginx
```
### 15.2 Changer de nom de domaine
```bash
cd /opt/voix-du-peuple
bash scripts/set-domain.sh https://nouveaudomaine.fr
systemctl reload nginx
```
Le QR code est régénéré automatiquement dans le build.
### 15.3 Changer la clé API Mistral
```bash
vim /opt/voix-du-peuple/.env
# Modifier MISTRAL_API_KEY
systemctl restart voix-du-peuple-api
```
### 15.4 Purger les contributions
```bash
psql -U voix_user -h 127.0.0.1 voix_du_peuple
```
```sql
-- Tout purger (irréversible sans backup)
TRUNCATE ideas;
TRUNCATE synthesis;
-- Supprimer seulement les refusées
DELETE FROM ideas WHERE accepted = false;
-- Forcer une re-synthèse au prochain envoi
DELETE FROM synthesis;
```
### 15.5 Consulter les logs
```bash
# Logs de l'API en temps réel
journalctl -u voix-du-peuple-api -f
# Logs d'accès Gunicorn
tail -f /var/log/voix-du-peuple/api-access.log
# Logs d'erreur Gunicorn
tail -f /var/log/voix-du-peuple/api-error.log
# Logs Nginx
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
```
### 15.6 Rotation des logs
```bash
# Créer un fichier logrotate
cat > /etc/logrotate.d/voix-du-peuple <<EOF
/var/log/voix-du-peuple/*.log {
daily
rotate 14
compress
missingok
notifempty
postrotate
systemctl kill -s USR1 voix-du-peuple-api
endscript
}
EOF
```
### 15.7 Vérification de santé (cron)
```bash
# Ajouter un health check toutes les 5 minutes
crontab -e
# Ajouter :
# */5 * * * * curl -sf http://127.0.0.1:8080/health || systemctl restart voix-du-peuple-api
```
### 15.8 Tableau de bord des commandes rapides
| Opération | Commande |
|-----------|----------|
| Statut global | `systemctl status voix-du-peuple-api nginx postgresql-15` |
| Relancer l'API | `systemctl restart voix-du-peuple-api` |
| Recharger Nginx | `systemctl reload nginx` |
| Logs API live | `journalctl -u voix-du-peuple-api -f` |
| Mise à jour complète | `git pull && bash scripts/set-domain.sh $VITE_APP_URL && systemctl restart voix-du-peuple-api && systemctl reload nginx` |
| Changer de domaine | `bash scripts/set-domain.sh https://domaine.fr` |
| Backup BDD | `pg_dump -U voix_user -h 127.0.0.1 voix_du_peuple > backup.sql` |
| Purger les données | `psql -U voix_user -h 127.0.0.1 voix_du_peuple -c "TRUNCATE ideas; TRUNCATE synthesis;"` |
| Health check | `curl http://127.0.0.1:8080/health` |