Some checks failed
Deploy to Production / Build and Deploy (push) Has been cancelled
10 KiB
10 KiB
Disaster Recovery — Wordly.art
Guide opérationnel complet
Architecture
[ Internet ]
│
▼ (80/443)
┌────────────────────────────────────┐
│ NPM dédié : 192.168.1.184 │ ← STABLE (ne tombe pas)
│ Interface admin : :81 │
└────────────┬───────────────────────┘
│ Forward Hostname → IP du serveur actif
▼
┌────────────────────────────────────┐
│ Serveur APP : 192.168.1.151 │ ← PEUT CRASHER
│ Docker: postgres, redis, │
│ backend:8001, frontend:3000│
└────────────┬───────────────────────┘
│ rsync SSH toutes les 6h (cron)
▼
┌────────────────────────────────────────────────┐
│ NAS Synology : 192.168.1.146 │ ← SOURCE DE VÉRITÉ
│ Chemin réel : /volume1/backups/wordly │
│ Accès : SSH key (wordly-backup@nas) │
│ Pas de montage CIFS — rsync direct │
└────────────┬───────────────────────────────────┘
│ (en cas de crash de .151)
▼
┌────────────────────────────────────┐
│ Serveur SECOURS : 192.168.1.98 │ ← Docker déjà installé
│ Restaure via rsync SSH depuis NAS│
│ → NPM redirigé automatiquement │
└────────────────────────────────────┘
Pourquoi rsync SSH et pas CIFS/SMB ?
- Pas de montage à gérer, pas de
/etc/fstabà configurer - Fonctionne même si le NAS redémarre (pas de montage stale)
- Chemin exact
/volume1/backups/wordlyutilisable directement - SSH chiffré, clé sans mot de passe pour l'automatisation
RPO / RTO
| Scénario | Données perdues max | Temps de remise en route | Procédure |
|---|---|---|---|
| Container crashe | 0 | ~30s | Autorestart Docker |
| Process PostgreSQL crashe | 0–5s | ~1 min | Autorestart + WAL |
| Corruption DB partielle | 0–6h | ~5 min | Restore depuis NAS |
| Serveur .151 mort | 0–6h | ~25 min | Restore NAS sur .98 + NPM auto |
| Erreur humaine (DROP) | 0–6h | ~5 min | Restore snapshot précédent |
Ce qui est sauvegardé
| Composant | Sauvegardé | Fréquence |
|---|---|---|
PostgreSQL pg_dump |
✅ | Toutes les 6h |
.env (secrets, clés API, Stripe...) |
✅ | Dans chaque archive DR |
docker-compose.yml |
✅ | Dans chaque archive DR |
Dossier docker/ (configs) |
✅ | Dans chaque archive DR |
| Redis | ❌ | Cache — sessions perdues à la restore (reconnexion users) |
| Config NPM | ❌ | NPM sur .184 (stable). Seul Forward Host change via API. |
| Métriques Prometheus | ❌ | Non critique, repart de zéro |
1. SETUP INITIAL (une seule fois sur .151)
Étape 1 : Créer le compte sur le NAS Synology
Connectez-vous à l'interface DSM : http://192.168.1.146:5000
1a. Créer l'utilisateur dédié
DSM → Panneau de configuration → Utilisateurs et groupes → Créer
Nom d'utilisateur : wordly-backup
Mot de passe : [choisissez un mot de passe fort]
☑ L'utilisateur ne peut pas changer son mot de passe
→ Suivant
Permissions sur les dossiers partagés :
backups → ☑ Lecture/Écriture
→ Suivant → Terminer
1b. Activer SSH sur le NAS
DSM → Panneau de configuration → Terminal et SNMP
☑ Activer le service SSH
Port : 22 (ou autre si vous avez changé)
→ Appliquer
1c. Créer le dossier wordly sur le NAS
# Depuis votre poste (ou n'importe quelle machine sur le réseau) :
ssh admin@192.168.1.146
mkdir -p /volume1/backups/wordly/snapshots
mkdir -p /volume1/backups/wordly/scripts
chown -R wordly-backup:users /volume1/backups/wordly
exit
Étape 2 : Configurer les variables dans .env sur .151
# ── NAS SSH ───────────────────────────────────
NAS_HOST=192.168.1.146
NAS_USER=wordly-backup
NAS_PATH=/volume1/backups/wordly
NAS_SSH_PORT=22
NAS_SSH_KEY=/root/.ssh/wordly_nas_key
# ── Alertes Telegram ──────────────────────────
TELEGRAM_BOT_TOKEN= # Voir section "Créer un bot Telegram" ci-dessous
TELEGRAM_CHAT_ID= # Votre chat ID personnel
# ── NPM Failover API ──────────────────────────
NPM_API_URL=http://192.168.1.184:81/api
NPM_ADMIN_EMAIL=admin@wordly.art
NPM_ADMIN_PASSWORD=VotreMotDePasseNPM
NPM_PROXY_HOST_DOMAIN=wordly.art
# ── Rétention ────────────────────────────────
DAILY_RETENTION=7
WEEKLY_RETENTION=4
MONTHLY_RETENTION=6
DR_RETENTION_DAYS=30
Étape 3 : Créer un bot Telegram (5 minutes)
- Ouvrir Telegram → chercher @BotFather
- Envoyer
/newbot - Nom :
Wordly Monitoring/ Username :wordly_monitor_bot - Copier le token →
TELEGRAM_BOT_TOKEN - Envoyer un message à votre bot
- Aller sur
https://api.telegram.org/bot<TOKEN>/getUpdates - Copier le
chat.id→TELEGRAM_CHAT_ID
Étape 4 : Configurer SSH sans mot de passe vers le NAS
# Sur le serveur .151 (en root)
sudo bash scripts/setup-nas.sh
Ce script :
- Génère une clé SSH dédiée :
/root/.ssh/wordly_nas_key - La copie sur le NAS (mot de passe demandé une seule fois)
- Teste la connexion sans mot de passe
- Crée la structure de dossiers sur le NAS
- Configure
~/.ssh/configavec l'aliaswordly-nas - Copie les scripts sur le NAS (disponibles depuis
.98pour la restauration)
Étape 5 : Tester le premier backup
bash scripts/backup-to-nas.sh --full
# Vérifier que l'archive est bien arrivée sur le NAS
bash scripts/backup-to-nas.sh --list
Étape 6 : Tester la vérification automatique
bash scripts/verify-backups.sh
Étape 7 : Tester le failover NPM (sans rien changer)
bash scripts/npm-failover.sh --dry-run --target-ip 192.168.1.98
Étape 8 : Activer les crons
bash scripts/install-crontab.sh
crontab -l # Vérifier
2. VÉRIFICATION QUOTIDIENNE (automatique)
0 */6 * * * backup-to-nas.sh → Snapshot DB + archive → NAS via rsync SSH
30 */6 * * * verify-backups.sh → 8 vérifications + alerte Telegram si erreur
3. RESTAURATION D'URGENCE (quand .151 est mort)
Durée estimée : 20–25 minutes
Sur le serveur de secours 192.168.1.98
# 1. Installer les prérequis (Docker déjà installé)
apt-get install -y rsync jq
# 2. Récupérer la clé SSH depuis le NAS (ou depuis une autre source sécurisée)
# Option A : copier la clé depuis un endroit sûr (gestionnaire de mots de passe, etc.)
mkdir -p /root/.ssh && chmod 700 /root/.ssh
# collez le contenu de /root/.ssh/wordly_nas_key ici
nano /root/.ssh/wordly_nas_key
chmod 600 /root/.ssh/wordly_nas_key
# 3. Tester la connexion NAS
ssh -i /root/.ssh/wordly_nas_key wordly-backup@192.168.1.146 "echo OK"
# 4. Voir les archives disponibles
ssh -i /root/.ssh/wordly_nas_key wordly-backup@192.168.1.146 \
"ls -lht /volume1/backups/wordly/snapshots/ | head -10"
# 5. Télécharger la dernière archive depuis le NAS
rsync -az \
-e "ssh -i /root/.ssh/wordly_nas_key" \
wordly-backup@192.168.1.146:/volume1/backups/wordly/snapshots/wordly_dr_TIMESTAMP.tar.gz \
/tmp/
# 6. Télécharger les scripts de restauration depuis le NAS
rsync -az \
-e "ssh -i /root/.ssh/wordly_nas_key" \
wordly-backup@192.168.1.146:/volume1/backups/wordly/scripts/ \
/opt/wordly/scripts/
# 7. Lancer la restauration complète
bash /opt/wordly/scripts/disaster-recovery.sh \
--restore /tmp/wordly_dr_TIMESTAMP.tar.gz
Le script fait automatiquement :
- Extrait
.env,docker-compose.yml, configs Docker - Lance tous les containers Docker
- Attend que PostgreSQL soit healthy
- Restaure le dump SQL
- Health check sur
http://localhost:8001/health(max 180s) - Si OK → appelle NPM API → bascule le trafic vers
192.168.1.98 - Alerte Telegram : "✅ Wordly.art DR COMPLET"
Si NPM failover automatique échoue (dernier recours) :
http://192.168.1.184:81 → Proxy Hosts → wordly.art → Edit
Forward Hostname : 192.168.1.98
→ Save
# Changement immédiat, 0 redémarrage nécessaire
4. CONSERVATION DE LA CLÉ SSH NAS
Important
La clé
/root/.ssh/wordly_nas_keyest critique pour la restauration depuis.98. Conservez-la dans au minimum 2 endroits sécurisés :
- Gestionnaire de mots de passe (Bitwarden, 1Password, etc.)
- Coffre-fort KeePass chiffré sur un support physique
Sans cette clé, vous ne pouvez pas accéder aux archives sur le NAS depuis
.98.
5. SCRIPTS DE RÉFÉRENCE
| Script | Usage | Déclenchement |
|---|---|---|
setup-nas.sh |
Configure SSH → NAS, génère clé, copie scripts | Once (root requis) |
backup-to-nas.sh |
pg_dump + archive DR → NAS via rsync SSH | Cron toutes les 6h |
backup-to-nas.sh --list |
Lister les archives disponibles sur le NAS | Manuel |
verify-backups.sh |
8 checks intégrité + Telegram | Cron toutes les 6h+30m |
disaster-recovery.sh --backup |
Archive DR → NAS | Inclus dans backup-to-nas |
disaster-recovery.sh --restore <archive> |
Restauration complète | Urgence |
npm-failover.sh --target-ip <IP> |
Bascule NPM vers une IP | Appelé automatiquement |
npm-failover.sh --dry-run --target-ip <IP> |
Test sans modifier NPM | Test initial |
install-crontab.sh |
Installe les crons | Once |
6. LOGS
# Logs backup (sur .151)
tail -f /var/log/wordly-backup.log
# Logs vérification (sur .151)
tail -f /var/log/wordly-verify.log
# Logs Docker (sur le serveur actif)
docker compose logs -f backend
docker compose logs -f postgres