# 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/wordly` utilisable 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

```bash
# 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`

```bash
# ── 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)

1. Ouvrir Telegram → chercher **@BotFather**
2. Envoyer `/newbot`
3. Nom : `Wordly Monitoring` / Username : `wordly_monitor_bot`
4. Copier le token → `TELEGRAM_BOT_TOKEN`
5. Envoyer un message à votre bot
6. Aller sur `https://api.telegram.org/bot<TOKEN>/getUpdates`
7. Copier le `chat.id` → `TELEGRAM_CHAT_ID`

---

### Étape 4 : Configurer SSH sans mot de passe vers le NAS

```bash
# 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/config` avec l'alias `wordly-nas`
- Copie les scripts sur le NAS (disponibles depuis `.98` pour la restauration)

---

### Étape 5 : Tester le premier backup

```bash
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
bash scripts/verify-backups.sh
```

---

### Étape 7 : Tester le failover NPM (sans rien changer)

```bash
bash scripts/npm-failover.sh --dry-run --target-ip 192.168.1.98
```

---

### Étape 8 : Activer les crons

```bash
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`

```bash
# 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 :**
1. Extrait `.env`, `docker-compose.yml`, configs Docker
2. Lance tous les containers Docker
3. Attend que PostgreSQL soit healthy
4. Restaure le dump SQL
5. Health check sur `http://localhost:8001/health` (max 180s)
6. **Si OK → appelle NPM API → bascule le trafic vers `192.168.1.98`**
7. **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_key` est **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

```bash
# 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
```
