Remplace les références obsolètes note.parsanet.org / notes.parsanet.org dans les guides de déploiement et l'exemple Docker. Co-authored-by: Cursor <cursoragent@cursor.com>
12 KiB
12 KiB
Memento — Guide Production : Monitoring, Backups & Résilience
Architecture de production
┌─────────────────────────────────────────────────────────┐
│ Serveur 192.168.1.190 (Proxmox) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ memento-note │ │ memento- │ │ memento- │ │
│ │ :3000 │ │ postgres │ │ redis │ │
│ │ (Next.js) │ │ :5433 │ │ :6379 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Stack Monitoring │ │
│ │ Prometheus:9090 / Grafana:3001 / Alertmanager │ │
│ │ node-exporter / postgres-exporter / redis-exp. │ │
│ │ cadvisor │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Backups │ │
│ │ /opt/memento/backups/snapshots/ (pg_dump 6h) │ │
│ │ /opt/memento/backups/wal/ (WAL continu) │ │
│ │ Serveur externe (rsync journalier)│
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│ │
│ Cloudflare │ rsync chiffré
▼ ▼
memento-note.com Serveur hors-site
1. Protection des données
1.1 Niveaux de sauvegarde
| Niveau | Méthode | Fréquence | RPO | Rétention |
|---|---|---|---|---|
| 1 | WAL archiving (PITR) | Continu | ~1 seconde | 30 jours WAL |
| 2 | pg_dump --format=custom | Toutes les 6h | 6h max | 7 jours + 4 snapshots hebdo |
| 3 | rsync chiffré hors-site | Journalier 03h00 | 24h max | Même rétention que niveau 2 |
| 4 | Pre-migration dump | Avant chaque deploy | Déploiement | 10 derniers |
RPO (Recovery Point Objective) : quantité maximale de données qu'on peut perdre. RTO (Recovery Time Objective) : temps pour retrouver un service fonctionnel.
1.2 Scénarios de reprise
| Scénario | RPO | RTO | Procédure |
|---|---|---|---|
| Crash container app | 0 | ~30s | Docker restart automatique |
| Crash process PostgreSQL | 0-5s | ~1min | Autorestart + WAL replay |
| Corruption DB partielle | 0-6h | ~5min | restore.sh snapshot |
| Corruption DB totale | 0-24h | ~15min | restore.sh snapshot + backup externe |
| Serveur physique perdu | 0-24h | ~2h | Restore from backup externe |
| Erreur humaine (DROP) | 0-6h | ~5min | restore.sh pitr "YYYY-MM-DD HH:MM:SS" |
1.3 Installation des sauvegardes
# Sur le serveur 192.168.1.190
cd /opt/memento
git pull
# 1. Configurer les variables dans .env.docker
# Ajouter :
# TELEGRAM_BOT_TOKEN=your_bot_token
# TELEGRAM_CHAT_ID=your_chat_id
# BACKUP_REMOTE_HOST=user@backup-server (optionnel, pour hors-site)
# 2. Activer le WAL archiving
bash scripts/backup/setup-wal.sh
# 3. Tester un snapshot manuel
bash scripts/backup/backup.sh
# 4. Vérifier le snapshot
bash scripts/backup/verify-backups.sh
# 5. Installer les crons
bash scripts/backup/install-crontab.sh
crontab /opt/memento/backups/crontab
# 6. Vérifier les crons
crontab -l
1.4 Crons installés
# Snapshots toutes les 6h (00h00, 06h00, 12h00, 18h00)
0 */6 * * * /opt/memento/scripts/backup/backup.sh
# Vérification 30min après chaque snapshot
30 */6 * * * /opt/memento/scripts/backup/verify-backups.sh
# Synchronisation hors-site quotidienne à 03h00
0 3 * * * /opt/memento/scripts/backup/offsite-sync.sh
1.5 Restauration
# Restaurer le dernier snapshot (automatique)
bash scripts/backup/restore.sh snapshot
# Restaurer un snapshot spécifique
bash scripts/backup/restore.sh snapshot /opt/memento/backups/snapshots/memento-20260517-120000.sql.gz
# Point-in-time recovery (PITR)
bash scripts/backup/restore.sh pitr "2026-05-17 14:30:00"
Le script restore.sh :
- Dump la DB actuelle (safety net)
- Stoppe l'app
- Restore la DB
- Vérifie le count de notes (abort si 0)
- Redémarre l'app
- Health check (180s timeout)
- Log le résultat
1.6 Script de vérification
verify-backups.sh vérifie toutes les 6h :
- ✅ Un snapshot récent existe (< 8h)
- ✅ Taille du snapshot > 1MB
- ✅ Intégrité gzip du snapshot
- ✅ DB contient des notes (count > 0)
- ✅ App répond (HTTP < 500)
- ✅ Espace disque < 85%
Si un check échoue → alerte Telegram immédiate.
2. Monitoring
2.1 Installation
# Sur le serveur 192.168.1.190
cd /opt/memento/monitoring
# Configurer le mot de passe Grafana
# Dans .env.docker, ajouter :
# GRAFANA_ADMIN_PASSWORD=your_secure_password
# Lancer la stack
docker compose -f docker-compose.monitoring.yml up -d
# Vérifier que tout est up
docker compose -f docker-compose.monitoring.yml ps
2.2 Accès
| Service | URL | Identifiants |
|---|---|---|
| Grafana | http://192.168.1.190:3001 | admin / (mot de passe configuré) |
| Prometheus | http://192.168.1.190:9090 | Aucun |
| Alertmanager | http://192.168.1.190:9093 | Aucun |
| cAdvisor | http://192.168.1.190:8080 | Aucun |
2.3 Exporters
| Exporter | Port | Ce qu'il monitor |
|---|---|---|
| node-exporter | 9100 | CPU, RAM, disque, réseau du serveur |
| postgres-exporter | 9187 | Connexions, requêtes, locks, taille DB |
| redis-exporter | 9121 | Hit rate, mémoire, clés, TTL |
| cadvisor | 8080 | CPU/RAM par conteneur Docker |
2.4 Alertes configurées
| Alerte | Condition | Sévérité |
|---|---|---|
| MementoAppDown | App injoignable > 2min | Critical |
| PostgresDown | PostgreSQL down > 1min | Critical |
| RedisDown | Redis down > 1min | Critical |
| DiskSpaceLow | Disque < 15% libre > 5min | Warning |
| HighMemoryUsage | RAM > 90% > 5min | Warning |
| PostgresConnectionsHigh | > 80 connexions > 5min | Warning |
| PostgresSlowQueries | Requête moyenne > 5s | Warning |
| HighErrorRate | Erreurs 5xx > 5% > 3min | Warning |
| ContainerRestarted | Restart dans la dernière heure | Warning |
2.5 Configuration Grafana
- Accéder à http://192.168.1.190:3001
- Ajouter la datasource Prometheus :
http://prometheus:9090 - Importer les dashboards (IDs Grafana) :
- 1860 — Node Exporter Full (serveur)
- 9628 — PostgreSQL Database (DB)
- 763 — Redis Dashboard (cache)
- 193 — Docker Monitoring (conteneurs)
2.6 Health API
GET https://memento-note.com/api/admin/health
Retourne :
{
"status": "healthy",
"uptime": 86400,
"version": "0.2.0",
"components": {
"database": { "status": "healthy", "latency": "12ms", "notes": 107 },
"redis": { "status": "healthy", "latency": "2ms", "keys": 847 },
"ai": { "status": "configured", "embedding": {"provider": "openrouter"} },
"storage": { "status": "healthy", "usagePercent": "23%" }
}
}
Utilisable par Prometheus, Grafana, ou tout outil de monitoring externe.
3. Déploiement
3.1 Pipeline CI/CD
Push → Gitea Actions CI → Lint + Test + Build
↓ (si succès)
Deploy.yaml
↓
Dump DB (vérif > 1MB)
↓
Git pull + Docker build
↓
Health check (180s)
↓ échec
Rollback automatique
↓ succès
Notification Telegram
3.2 Variables à configurer dans Gitea
Secrets :
SSH_PRIVATE_KEY— clé SSH pour le serveurPOSTGRES_PASSWORDNEXTAUTH_SECRETTELEGRAM_BOT_TOKENTELEGRAM_CHAT_IDCUSTOM_OPENAI_API_KEY
Variables :
APP_URL— https://memento-note.comADMIN_EMAILPOSTGRES_USER,POSTGRES_DB,POSTGRES_PORT- Toutes les variables AI provider
3.3 Rollback
Le CI tag l'image Docker actuelle en :rollback avant chaque deploy.
Si le health check échoue → restore automatique de l'image :rollback.
En cas de problème DB :
bash scripts/backup/restore.sh snapshot
4. Checklist production
Premier setup (à faire une seule fois)
bash scripts/backup/setup-wal.sh— activer WAL archivingbash scripts/backup/backup.sh— tester le premier snapshotbash scripts/backup/verify-backups.sh— vérifier le setup completcrontab /opt/memento/backups/crontab— installer les crons- Configurer
TELEGRAM_BOT_TOKEN+TELEGRAM_CHAT_IDdans.env.docker cd monitoring && docker compose -f docker-compose.monitoring.yml up -d- Configurer Grafana (datasource + dashboards)
- Configurer
BACKUP_REMOTE_HOSTpour le backup hors-site
Vérification quotidienne (automatique)
- Snapshots créés toutes les 6h ✓ (cron)
- Vérification automatique ✓ (cron)
- Sync hors-site journalier ✓ (cron)
- Alertes Telegram si problème ✓ (Alertmanager)
Vérification hebdomadaire (manuelle)
- Ouvrir Grafana, vérifier les dashboards
- Tester un restore sur une DB temporaire
- Vérifier l'espace disque et la rotation des backups
- Vérifier que les WAL ne grossissent pas trop
5. Sécurité
5.1 PostgreSQL
- WAL archiving activé (PITR possible)
archive_commandstocke les WAL dans/var/lib/postgresql/backups/wal/- Pas de connexion TRUST — md5/scram-sha-256 uniquement
- Container non exposé sur internet (port 5433 interne uniquement)
5.2 Backups
- Snapshots chiffrés si le filesystem est chiffré (recommandé LUKS)
- rsync hors-site via SSH (chiffré en transit)
- Permissions fichiers : 600 sur les snapshots
- Les scripts vérifient l'intégrité avant de trust un backup
5.3 App
DATABASE_URLjamais exposé côté client- Secrets dans Gitea (encrypted at rest)
.env.dockeren permission 600 sur le serveur- Rate limiting à configurer (P3)
6. Scripts de référence
| Script | Usage | Fréquence |
|---|---|---|
scripts/backup/setup-wal.sh |
Activer WAL archiving | Once |
scripts/backup/backup.sh |
Créer un snapshot | 6h (cron) |
scripts/backup/verify-backups.sh |
Vérifier les backups | 6h (cron) |
scripts/backup/restore.sh |
Restaurer la DB | Manuel (urgence) |
scripts/backup/offsite-sync.sh |
Sync hors-site | 24h (cron) |
scripts/backup/install-crontab.sh |
Installer les crons | Once |
dump-db.sh |
Dump rapide (dev) | Manuel |
scripts/deploy-prod.sh |
Deploy manuel | Manuel |
scripts/migrate-docker.sh |
Migrer la DB | Après deploy |