# Restauration — remettre en service ce qui a été perdu _Guide de reconstruction. Il décrit comment récupérer une base, un site, un conteneur ou une machine entière à partir des sauvegardes._ **Le fichier `.md` de cette page :** [ouvrir le `.md`](https://blog.infolaf.ca/wp-content/uploads/fichiers/guide-restauration-public.md) **Ce que cette page couvre :** restaurer, dans l'ordre du plus courant au plus grave — une base de données, un site web, un conteneur, la clé de démarrage du serveur, puis la machine entière. Elle suppose que les sauvegardes existent ; leur mise en place fait l'objet de la page **[Sauvegarde](https://blog.infolaf.ca/wiki/sauvegarde-strategie-methode/)**. **Cette page est écrite pour être lue dans l'urgence.** Peu de prose, les commandes en évidence, chaque section autonome. Si tu la lis un jour calme, la dernière section est celle qui compte : elle explique comment l'éprouver avant d'en avoir besoin. **Contexte :** un serveur Ubuntu qui héberge des conteneurs Incus, dont un conteneur web sous ISPConfig, et un NAS qui reçoit les sauvegardes. Les adresses, noms d'hôtes et chemins sont des exemples à transposer. **Convention : chaque bloc de commandes indique la machine où il s'exécute.** --- ## Le principe qui gouverne tout **Le chemin de restauration n'est pas l'inverse du chemin de sauvegarde.** Toutes les sauvegardes sont des *tirages* : la machine de sauvegarde va chercher les données par le démon rsync. Et **les modules sont en `read only = true`** — le démon ne peut donc rien réécrire. C'est délibéré : un démon en écriture permettrait d'écraser les originaux depuis le réseau avec le seul mot de passe. **Un seul module du parc est inscriptible** — celui qui téléverse les photos vers la galerie. Il ne vise qu'un répertoire : ce n'est pas un chemin de restauration. **Toute restauration passe par un autre canal** : `incus file push` pour un conteneur, `scp` ou `ssh` sinon. **Ne pas juger une sauvegarde à la date de ses fichiers.** `rsync -a` préserve la date de la source : un fichier daté de 2022 dans une sauvegarde faite cette nuit est parfaitement normal. C'est le journal qui dit si la copie a eu lieu, pas l'horodatage. --- ## Où sont les copies Quatre niveaux, et ils ne servent pas aux mêmes pannes. Savoir lequel ouvrir fait gagner le plus de temps. | Niveau | Contenu | Fraîcheur | À utiliser quand | |---|---|---|---| | **Quotidien** — `/media/nas1/Backups/` | Données des services, sites, vidages de bases | La nuit dernière | Perte d'un fichier, d'une base, d'un site | | **Mensuel** — `/media/nas1/Backups/incus-exports/` | Export complet des conteneurs, deux mois conservés | Le 1er du mois | Perte d'un conteneur entier | | **Hors site** — Proton Drive | Copie du mensuel, **plus l'image de la clé de démarrage** | Continu, versions conservées 30 jours | Perte de la machine : incendie, vol, panne | | **Disques externes** | nas1 et nas2, séparément | Jusqu'à deux mois | Erreur ancienne, corruption, rançongiciel — ils sont débranchés | ⚠️ **Un disque débranché depuis longtemps peut porter d'anciens noms de répertoires.** Les noms évoluent au fil des réorganisations, et un disque hors ligne ne suit pas. **Chercher large avant de conclure qu'une sauvegarde manque :** ```bash ls -d /media//Backups/*web-srv* ``` ⚠️ **Le hors site conserve les versions antérieures trente jours, pas davantage.** Une archive corrompue ou effacée par erreur reste récupérable pendant un mois ; passé ce délai, la version saine a disparu en ligne. Contre une erreur découverte tard — et contre une compromission du compte, qui atteindrait aussi les versions antérieures —, ce sont les **disques externes** qui protègent, précisément parce qu'ils sont débranchés. ⚠️ **`incus export` ne capture pas les disques montés depuis l'hôte.** L'archive mensuelle du conteneur web contient donc son système et ses vidages de bases, **mais pas le contenu de `/var/www`**. Ces fichiers-là ne sont hors site que par le disque externe. --- ## Restaurer une base de données Le cas le plus fréquent, et le plus simple. Les vidages sont produits avec `--databases` : ils contiennent leur propre `CREATE DATABASE` et `USE`, donc rien à créer au préalable. **Si le vidage est encore dans le conteneur** — c'est le cas courant, une base abîmée sur une machine saine. **[dans le conteneur web-srv]** ``` ls -l /home/webadmin/backups/mysql_DB/ ``` ``` mysql < /home/webadmin/backups/mysql_DB/c1blog.sql ``` Pas de `-u` ni de `-p` : les identifiants sont dans `~/.my.cnf` du compte `webadmin`. **Si le vidage local a été perdu**, le reprendre depuis le NAS. Le démon ne pouvant pas écrire, on pousse depuis l'hôte. **[nas-host]** ``` ls -l /media/nas1/Backups/web-srv_MySQL_db/ ``` ``` incus file push --uid 0 --gid 0 \ /media/nas1/Backups/web-srv_MySQL_db/c1blog.sql \ web-srv/home/webadmin/backups/mysql_DB/c1blog.sql ``` Puis l'import ci-dessus, dans le conteneur. ⚠️ **Vérifier la taille avant d'importer.** Un vidage tronqué s'importe sans erreur jusqu'à l'endroit où il s'arrête, et laisse une base à moitié remplie — plus difficile à diagnostiquer qu'une base vide. --- ## Restaurer un site web **[nas-host]** ``` ls -la /media/nas1/Backups/web-srv_www/ ``` ``` incus file push -r \ /media/nas1/Backups/web-srv_www/blog/ \ web-srv/var/www/clients/client1/web1/web/ ``` ⚠️ **Vérifier les propriétaires après restauration — c'est l'erreur classique.** Les modules rsync déclarent `uid = web1` et `gid = client1` ; une restauration par un autre canal ne les rétablit pas. **Un site dont les fichiers appartiennent à `root` ne fonctionne pas sous ISPConfig**, et le symptôme est une erreur 500 sans rapport apparent avec les permissions. **[dans le conteneur web-srv]** ``` ls -l /var/www/clients/client1/web1/web/ | head ``` ``` sudo chown -R web1:client1 /var/www/clients/client1/web1/web/ ``` Le contenu des sites n'étant pas dans l'archive mensuelle, si le NAS est perdu en même temps, la seule copie est le **disque externe 1** — avec jusqu'à deux mois de retard. ### Les fichiers de mots de passe, qui ne se voient pas ⚠️ **Sans eux, un site remonté répond — mais sa protection a disparu.** Deux fichiers d'authentification sont dans les sauvegardes, et un `ls` ordinaire ne les montre pas : ils commencent par un point. ``` /media/nas1/Backups/Config/web-srv/etc/apache2/.htpasswd-routeur /media/nas1/Backups/web-srv_www/webdav/utilisateur.htdigest ``` Le premier protège l'administration du routeur, le second le partage WebDAV. Celui du WebDAV revient avec le contenu du partage ; celui du routeur se repose à la main dans `/etc/apache2/`, car il n'appartient à aucun site. **Les chercher avec `find`, jamais avec `ls` :** ```bash find /media/nas1/Backups -name '.htpasswd*' -o -name '*.htdigest' ``` **L'export XML de WordPress n'est pas une sauvegarde du site** : articles et commentaires, mais ni fichiers téléversés, ni thème, ni extensions, ni réglages. Reconstruire depuis lui seul donne le texte sans les images, dans un thème par défaut. --- ## Restaurer un conteneur **[nas-host]** ``` ls -l /media/nas1/Backups/incus-exports/ ``` ``` incus import /media/nas1/Backups/incus-exports/2026-09/navidrome.tar.gz ``` ``` incus start navidrome ``` **Trois choses ne sont pas dans l'archive**, et il faut les rétablir à la main : 1. **Les périphériques disque montés depuis l'hôte.** Pour le conteneur web, le disque `web` doit être rattaché de nouveau — voir la page **[Sauvegarde](https://blog.infolaf.ca/wiki/sauvegarde-strategie-methode/)**, et la [page de l'hôte](https://blog.infolaf.ca/wiki/incus-hote-et-conteneur-serveur-nas/) pour la commande exacte. 2. **`boot.autostart`**, qui n'a pas nécessairement la valeur voulue après un import. 3. **Rien pour l'adresse IP** : elle est statique dans le netplan **du conteneur**, donc elle voyage avec lui. ⚠️ S'assurer en revanche que l'ancienne instance ne tourne pas déjà sur la même adresse — deux machines sur une même IP produisent des symptômes déroutants. **Vérifier une archive sans la restaurer**, ce qui est beaucoup plus rapide : ``` tar tzf /media/nas1/Backups/incus-exports/2026-09/web-srv.tar.gz \ > /dev/null && echo OK ``` --- ## Restaurer la configuration du serveur de musique Deux choses seulement ont été sauvegardées, et c'est délibéré : les **réglages** — lecteurs déclarés, favoris, et la base des écoutes, qu'aucune réanalyse ne rend — et le **code des extensions**. Tout le reste du cache du serveur se refabrique. 🔴 **Le chemin de restauration n'est pas l'inverse du chemin de sauvegarde, et deux détails décident du résultat.** Serveur **arrêté** : **[nas-host]** ```bash S=/media/nas1/Backups/Configuration_logiciels/lyrion sudo systemctl stop lyrionmusicserver sudo rsync -av "$S/prefs/" /var/lib/squeezeboxserver/prefs/ sudo cp "$S/persist.db" /var/lib/squeezeboxserver/prefs/persist.db sudo rm -f /var/lib/squeezeboxserver/prefs/persist.db-wal \ /var/lib/squeezeboxserver/prefs/persist.db-shm sudo rsync -av "$S/InstalledPlugins/" \ /var/lib/squeezeboxserver/cache/InstalledPlugins/ sudo chown -R squeezeboxserver:nogroup /var/lib/squeezeboxserver sudo systemctl start lyrionmusicserver ``` ⚠️ **Les fichiers `-wal` et `-shm` d'une ancienne session doivent être retirés.** Ce sont les journaux de transactions de la base **précédente**. Laissés à côté d'une base restaurée, SQLite tenterait de leur appliquer des écritures qui ne correspondent plus à elle — et le dégât ne se verrait qu'à l'usage, dans un historique d'écoute incohérent. ⚠️ **Le `chown` final n'est pas une politesse.** La copie a été faite par root ; sans lui, le serveur ne peut plus écrire dans ses propres réglages, et il démarre en donnant l'illusion de fonctionner. ℹ️ **Restaurer les extensions les rend sans passer par leurs dépôts**, donc sans dépendre de ce qu'Internet en aura fait entre-temps. C'est exactement ce que la sauvegarde de ce répertoire achète : un dépôt tiers disparu ne se retrouve pas, et le serveur efface lui-même la liste de ce qui était installé dès qu'il démarre sans les trouver. **La première analyse après une restauration est longue** — la bibliothèque et les pochettes se refabriquent entièrement. C'est normal, et c'est le prix accepté pour ne pas copier plusieurs gigaoctets chaque nuit. --- ## Restaurer la clé de démarrage du serveur `/boot` vit sur une clé USB, la carte mère ne sachant pas démarrer sur le NVMe en BIOS hérité. **Si elle lâche, la machine ne démarre plus** — et une copie déposée sur son propre disque serait inaccessible, puisqu'il faudrait démarrer pour la lire. L'image est donc répliquée **hors site**, chez Proton Drive. **C'est une image du périphérique entier** : table de partition, secteur d'amorçage, chargeur, contenu — **et l'UUID de la partition**, si bien que le `fstab` du système restauré reconnaît la nouvelle clé sans retouche. Elle est refaite à chaque changement de noyau, automatiquement ; le mécanisme est décrit dans la page [Sauvegarde](https://blog.infolaf.ca/wiki/sauvegarde-strategie-methode/). **Identifier la clé neuve — l'étape à ne pas bâcler.** **[nas-host]** ``` lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS,MODEL ``` 🔴 **`dd` écrit sans rien demander et sans rien pouvoir annuler.** Se tromper de périphérique détruit le disque visé en quelques secondes — et sur cette machine, les candidats voisins sont le NVMe du système et le disque de données de 12,7 To. Relever le nom **et la taille** dans la sortie ci-dessus, et vérifier que la taille correspond à une clé USB avant de taper la commande suivante. Dans le doute, débrancher la clé, relancer `lsblk`, la rebrancher, relancer : le nom qui apparaît est le bon. **Écrire l'image :** ``` gunzip -c /chemin/vers/boot-usb-AAAA-MM-JJ.img.gz \ | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync ``` `status=progress` affiche l'avancement — sans lui, `dd` reste muet pendant plusieurs minutes. `conv=fsync` force l'écriture réelle avant de rendre la main, faute de quoi la commande peut se terminer alors que des données sont encore en tampon. La décompression se fait à la volée, sans écrire l'image entière au passage ; `sudo` ne porte que sur `dd`, qui est seul à écrire sur le périphérique. **Vérifier avant de redémarrer :** ``` sudo blkid /dev/sdX* ``` ``` grep boot /etc/fstab ``` L'UUID rendu par `blkid` doit être celui qu'attend le `fstab`. S'ils diffèrent, l'image ne correspond pas à ce système. ⚠️ **La clé neuve doit être au moins aussi grande que l'image.** Une image de 16 Go ne s'écrit pas sur une clé de 16 Go d'une autre marque, celles-ci différant de quelques mégaoctets. Prendre plus grand : l'espace excédentaire reste simplement inutilisé. **Une image périmée reste utile** : elle rend la clé amorçable, avec la bonne table de partition et le bon UUID — la partie qu'on ne saurait pas refaire de mémoire. Le reste se régénère par `grub-install` et `update-grub` une fois le système démarré. Elle ne devient inutilisable que si plus aucun noyau qu'elle contient n'est présent sur le disque système. ⚠️ **Cette procédure n'a pas encore été éprouvée sur cette machine** : elle est écrite d'après la nature de la copie, non d'après un essai réussi. L'éprouver demande une clé de rechange et un redémarrage — à faire un jour calme. --- ## Perte totale du serveur L'ordre compte : chaque étape dépend de la précédente. **1. Matériel et système.** Réinstaller Ubuntu Server en suivant la [page de l'hôte](https://blog.infolaf.ca/wiki/incus-hote-et-conteneur-serveur-nas/). ⚠️ Si la carte mère est la même, refaire le montage `/boot` sur clé USB avant tout le reste — c'est une décision de partitionnement, elle ne se rattrape pas après coup. **2. Incus.** Dépôt Zabbly `lts-6.0`, **épinglé à 600** — sans quoi apt installe silencieusement la version d'Ubuntu, plus ancienne. Pool ZFS nommé `local`. Profils `default` et `macvlan`, ce dernier avec `parent: eno1`. **3. Les conteneurs**, depuis Proton Drive. `incus import` pour chacun. Ils reviennent avec leurs adresses statiques, leurs configurations, et — pour le conteneur web — les vidages de bases du mois. **4. Le disque web.** Recréer la partition, puis rattacher le périphérique au conteneur. **5. Le contenu des sites.** Depuis le NAS si son disque est récupérable ; sinon depuis le **disque externe 1**, avec jusqu'à deux mois de retard. Méthode et avertissement sur les propriétaires : voir plus haut. **6. Les bases**, depuis les vidages du conteneur restauré. **7. Les services de l'hôte** — partages de fichiers, diffusion audio, serveur de musique — depuis les sauvegardes de configuration, si le NAS est récupérable. ⚠️ **Le système d'exploitation n'est restauré par aucune sauvegarde** : il est **reconstruit depuis le wiki**. C'est un choix — une image système se périme, une procédure écrite se met à jour. Il implique que **la qualité de ces pages est un composant de la sauvegarde**. --- ## Ouvrir le disque externe chiffré Le disque 1 est chiffré avec VeraCrypt : toute restauration depuis lui exige un mot de passe. Ce mot de passe est rangé dans **deux gestionnaires indépendants** — Proton Pass, hors site, et une base KeePassXC sur les appareils mobiles. **Aucun des deux n'est enfermé dans le disque qu'il sert à ouvrir** : la dépendance circulaire — le mot de passe du disque de secours rangé dans le disque de secours — n'existe pas ici. ⚠️ **Ouvrir ce disque sans son propriétaire exige un accès à Proton Pass.** Le chiffrement qui rend acceptable de confier le disque à un tiers est le même qui le rend inutilisable sans lui. C'est un arbitrage à décider à l'avance, pas dans l'urgence. --- ## Éprouver cette page avant d'en avoir besoin **Une sauvegarde jamais restaurée est une hypothèse, pas une sauvegarde.** Et une procédure de restauration jamais suivie est une fiction rassurante. **Deux fois l'an**, le plus petit essai utile — il valide d'un coup l'archive, la procédure, et le souvenir qu'on en a : **[nas-host]** ``` incus import \ /media/nas1/Backups/incus-exports/2026-09/languagetool.tar.gz \ languagetool-essai ``` ``` incus start languagetool-essai ``` Vérifier que le service répond, puis supprimer l'instance d'essai. Choisir le conteneur le plus léger et le moins critique. **Le nom donné en second argument crée une instance distincte** plutôt que d'écraser celle qui tourne. C'est ce qui rend l'essai sans risque. **Une fois l'an**, vérifier que chaque module de sauvegarde répond encore : un module dont le chemin a disparu échoue chaque nuit sans rien dire. ```bash P=/home/hostadmin/scripts/rsync/auto/rsync_pass for m in $(rsync --list-only --password-file=$P test@192.168.0.11:: \ | awk '{print $1}'); do printf '%-26s ' "$m" rsync --list-only --password-file=$P "test@192.168.0.11::$m/" \ >/dev/null 2>&1 && echo OK || echo ÉCHEC done ``` À répéter en changeant l'adresse pour chaque machine du parc. Dix secondes chacune. **Le gain :** le mécanisme est éprouvé et confirmé fonctionnel, ce qui évite des sauvegardes qui échouent en silence.