Use Snapper instead of a custom script for BTRFS snapshots

This commit is contained in:
Djeex
2026-09-09 13:18:59 +02:00
parent a59966006b
commit c90cd781d3
4 changed files with 146 additions and 178 deletions
@@ -89,6 +89,10 @@ Confirmez le fuseau horaire deviné à partir de votre pays.
*Assisté, utiliser un disque entier* sur le disque système, puis *Tout dans une seule partition*, ce qui vous donne un gros `/` plus une partition de swap. Des partitions `/home` ou `/var` séparées n'apportent pas grand-chose ici et garantissent surtout que l'une se remplit pendant que les autres restent à moitié vides. Ne prenez LVM que si vous savez déjà que vous voulez des snapshots ou agrandir des volumes plus tard. Vos disques de données ne sont pas touchés à ce stade, vous les monterez ensuite.
::warning{to="/serveex/advanced/btrfs-snapshots"}
__Pour les utilisateurs avancés :__ c'est maintenant qu'il faut décider, pas plus tard. Choisir *Manuel* ici plutôt qu'*Assisté* permet de formater la partition racine en Btrfs plutôt qu'en ext4, ce qui débloque des snapshots instantanés et quasi gratuits vers lesquels revenir avant une mise à jour risquée ou un changement de config. Une fois cette étape passée et Debian installé en ext4, passer à Btrfs n'est plus possible sans effacer le disque et tout recommencer. Voir **Snapshots BTRFS** pour la mise en place, ça ne remplace pas non plus de vraies sauvegardes, un snapshot vit sur le même disque.
::
Terminez avec *Terminer le partitionnement et appliquer les changements*, puis confirmez avec *Oui* : c'est le point de non-retour pour ce disque.
![Schéma de partitionnement de l'installateur Debian, tout dans une seule partition](/img/serveex/install/debian-install-partition.png)
@@ -97,10 +101,6 @@ Terminez avec *Terminer le partitionnement et appliquer les changements*, puis c
__Astuce :__ ce qui vit réellement sur cette unique partition, et pourquoi `/srv/docker` est l'endroit où ce guide place chaque stack, est traité dans **dossiers et partitions**.
::
::tip{icon="" to="/serveex/advanced/btrfs-snapshots"}
__Pour les utilisateurs avancés :__ choisir *Manuel* ici plutôt qu'*Assisté* permet de formater la partition racine en Btrfs plutôt qu'en ext4, ce qui débloque des snapshots instantanés et quasi gratuits vers lesquels revenir avant une mise à jour risquée ou un changement de config. Ça ne remplace pas de vraies sauvegardes, un snapshot vit sur le même disque, voir **Snapshots BTRFS** pour la mise en place.
::
#### Miroir et sondages
Répondez *Non* à *Faut-il analyser un autre média d'installation ?*, tout le reste vient du réseau. Pour le miroir, prenez-en un dans votre pays, ou `deb.debian.org` qui route automatiquement vers un miroir proche, et laissez le champ du proxy HTTP vide sauf si vous en avez réellement un. Le concours de popularité (statistiques anonymes sur les paquets) est oui ou non, sans conséquence.
@@ -1,6 +1,6 @@
---
title: Snapshots BTRFS
description: Formater la partition racine de Debian en BTRFS et utiliser les snapshots pour annuler instantanément une mise à jour ratée ou un mauvais changement de config, en complément local des sauvegardes 3-2-1 hors site de Backrest.
description: Formater la partition racine de Debian en BTRFS et utiliser Snapper pour annuler instantanément une mise à jour ratée ou un mauvais changement de config, en complément local des sauvegardes 3-2-1 hors site de Backrest.
---
@@ -50,118 +50,102 @@ Donnez à la partition le reste du disque (moins une petite partition EFI si vou
Tout le reste de [l'installeur](/serveex/core/installation#installer-debian) reste identique.
## Prendre un snapshot
Un snapshot se crée avec une seule commande, et se termine instantanément quelle que soit la quantité de données sur le disque, puisque Btrfs ne commence à copier des blocs qu'au moment où quelque chose change réellement (copy-on-write) :
## Installer Snapper
Plutôt que de jongler à la main avec des commandes `btrfs subvolume` brutes, [Snapper](https://github.com/openSUSE/snapper) est un petit outil qui gère tout le cycle de vie des snapshots : les créer, les ranger proprement, supprimer les anciens, et encadrer automatiquement chaque opération `apt` d'une paire de snapshots.
```bash [Terminal]
sudo mkdir -p /.snapshots
sudo btrfs subvolume snapshot -r / /.snapshots/$(date +%F_%H-%M-%S)
sudo apt install snapper
sudo snapper -c root create-config /
```
- `-r` le rend **en lecture seule**, ce qui est ce qu'on veut pour un filet de sécurité : rien, pas même vous par erreur, ne peut modifier un snapshot après coup.
- Stocker les snapshots sous `/.snapshots` les garde hors du chemin, et Btrfs est assez malin pour ne pas descendre dans un sous-volume la prochaine fois que vous snapshotez `/` lui-même, donc les snapshots ne finissent jamais par contenir d'anciens snapshots.
`create-config` enregistre une configuration nommée `root` pour le système de fichiers `/`, et crée un sous-volume `.snapshots` dédié en dessous pour y stocker chaque snapshot, verrouillé pour root uniquement. Pas besoin de découpage `@`/`@home`, ça fonctionne très bien sur le layout à sous-volume unique que le partitionnement manuel vient de créer.
Prenez l'habitude de lancer ça avant tout ce qui pourrait mal tourner : un `sudo apt full-upgrade`, la modification d'une unité systemd, ou un changement Docker Compose qui touche à autre chose que `/srv/docker`.
Activez la configuration en éditant `/etc/default/snapper` :
::tip
✨ Donnez au snapshot un nom qui veut dire quelque chose plutôt qu'un simple horodatage, par exemple `/.snapshots/avant-upgrade-2026-09-09`, pour savoir pourquoi il est là quand vous le retrouverez trois semaines plus tard.
::
```properties [/etc/default/snapper]
SNAPPER_CONFIGS="root"
```
## Restaurer des fichiers depuis un snapshot
Un snapshot n'est qu'un dossier : tout ce à quoi ressemblait le système de fichiers à cet instant, consultable comme n'importe quel autre répertoire.
Puis activez les timers qui exécutent les snapshots périodiques et le nettoyage de Snapper :
```bash [Terminal]
ls /.snapshots/2026-09-09_18-30-00/etc/ssh/
sudo systemctl enable --now snapper-timeline.timer snapper-cleanup.timer
```
Pour annuler une bêtise, recopiez le fichier (ou le dossier) depuis le snapshot par-dessus le fichier actuel :
```bash [Terminal]
sudo cp -a /.snapshots/2026-09-09_18-30-00/etc/ssh/sshd_config /etc/ssh/sshd_config
```
`-a` préserve les permissions et le propriétaire, ce qui compte pour tout ce qui se trouve sous `/etc`.
::note
Ça couvre l'immense majorité des vrais accidents de homelab : une mauvaise config, un fichier supprimé, une mise à jour de paquet qui a cassé un truc. Revenir en arrière sur __l'intégralité__ de la partition racine (pour un système qui ne démarre plus du tout) est aussi possible, en renommant des sous-volumes depuis une clé USB live, mais c'est une opération plus délicate et bien plus rare. La [documentation Btrfs](https://btrfs.readthedocs.io/en/latest/Subvolumes.html) couvre ce cas si vous en avez un jour besoin, et honnêtement, si on en arrive là, c'est exactement le scénario pour lequel votre sauvegarde [Backrest](/serveex/advanced/backrest) hors site existe.
Le paquet Debian embarque aussi un hook APT (`/etc/apt/apt.conf.d/80snapper`) qui s'active dès qu'une configuration figure dans `SNAPPER_CONFIGS` : à partir de maintenant, chaque `apt install`, `apt upgrade` ou `apt full-upgrade` obtient automatiquement un snapshot juste avant et juste après son exécution, sans aucun effort de votre part.
::
## Gérer les snapshots
## Prendre un snapshot
Pour tout ce qui sort du cadre d'apt, comme modifier une unité systemd ou un fichier Docker Compose, prenez-en un vous-même avec une description qui voudra vraiment dire quelque chose plus tard :
```bash [Terminal]
sudo btrfs subvolume list /
sudo snapper create --description "avant changement compose sur swag"
```
Liste tous les sous-volumes du système de fichiers, snapshots compris, chacun avec son propre ID. Supprimez-en un dont vous n'avez plus besoin avec :
Listez-les tous avec :
```bash [Terminal]
sudo btrfs subvolume delete /.snapshots/2026-09-09_18-30-00
sudo snapper list
```
::caution
```console [Output]
# | Type | Pre # | Date | Description
---+--------+-------+--------------------------+---------------------------------
0 | single | | | current
1 | single | | Tue 09 Sep 2026 18:30:00 | avant changement compose sur swag
2 | pre | | Tue 09 Sep 2026 19:00:01 | apt install unattended-upgrades
3 | post | 2 | Tue 09 Sep 2026 19:00:14 | apt install unattended-upgrades
```
Les snapshots sont bon marché, pas gratuits : dès que le système de fichiers actif diverge d'un snapshot, les anciens blocs restent occupés tant que le snapshot les référence. Un tas de vieux snapshots sur un serveur qui change beaucoup (images de conteneurs, logs) peut discrètement grignoter de l'espace disque réel. Vérifiez avec `df -h /` et supprimez ce dont vous n'avez plus besoin.
## Restaurer des fichiers depuis un snapshot
Snapper conserve l'état complet du système de fichiers au moment du snapshot sous `/.snapshots/<numéro>/snapshot`, consultable comme n'importe quel autre dossier :
```bash [Terminal]
ls /.snapshots/1/snapshot/etc/ssh/
```
Pour voir exactement ce qui a changé entre un snapshot et le système actuel (`0` désigne toujours "l'état actuel") avant de toucher à quoi que ce soit :
```bash [Terminal]
sudo snapper status 1..0
```
Ça affiche chaque fichier créé, modifié ou supprimé depuis. Pour annuler ces changements automatiquement :
```bash [Terminal]
sudo snapper undochange 1..0
```
Ou restaurez un seul fichier à la main, souvent le choix le plus sûr et le plus chirurgical :
```bash [Terminal]
sudo cp -a /.snapshots/1/snapshot/etc/ssh/sshd_config /etc/ssh/sshd_config
```
::note
Ça couvre l'immense majorité des vrais accidents de homelab : une mauvaise config, un fichier supprimé, une mise à jour de paquet qui a cassé un truc. Snapper peut aussi faire un `rollback` de toute la partition racine vers un snapshot antérieur (il crée un nouveau sous-volume par défaut et démarre dessus au prochain redémarrage), pour un système dans un état vraiment cassé plutôt qu'un simple fichier manquant. C'est une opération plus délicate et bien plus rare, à tester une fois sur une machine où redémarrer ne vous dérange pas, avant d'en avoir vraiment besoin. Et si le disque lui-même est le problème, c'est exactement le scénario pour lequel votre sauvegarde [Backrest](/serveex/advanced/backrest) hors site existe.
::
## Automatiser les snapshots
Plutôt que de penser à lancer la commande à la main, un petit script associé à un timer systemd en prend un automatiquement et supprime les anciens :
## Gérer et nettoyer les snapshots
Les snapshots sont bon marché, pas gratuits : dès que le système de fichiers actif diverge d'un snapshot, les anciens blocs qu'il référence toujours restent occupés. Sans surveillance, des mois de snapshots sur un serveur qui change beaucoup (images de conteneurs, logs) peuvent discrètement grignoter de l'espace disque réel.
Le `snapper-cleanup.timer` activé plus haut nettoie déjà automatiquement, selon la configuration de `/etc/snapper/configs/root` :
| Réglage | Défaut | Ce que ça fait |
|---------|---------|---------------|
| `TIMELINE_LIMIT_HOURLY` / `_DAILY` / `_MONTHLY` / `_YEARLY` | `10` | Combien de snapshots de chronologie garder pour chaque granularité |
| `TIMELINE_LIMIT_WEEKLY` | `0` | Désactivé par défaut |
| `NUMBER_LIMIT` | `50` | Combien de snapshots manuels (`single`) garder |
Ajustez ça à votre goût, puis supprimez-en un immédiatement à la main si vous avez besoin de la place tout de suite :
```bash [Terminal]
sudo nano /usr/local/bin/btrfs-snapshot.sh
sudo snapper delete 1
```
```bash [btrfs-snapshot.sh]
#!/bin/bash
set -e
mkdir -p /.snapshots
btrfs subvolume snapshot -r / "/.snapshots/$(date +%F_%H-%M-%S)"
Vérifiez l'usage disque réel avec `df -h /` : les chiffres ci-dessus ne plafonnent que le nombre de snapshots, pas l'espace qu'un serveur très actif peut encore consommer entre deux nettoyages.
# Ne garde que les 7 snapshots les plus récents
cd /.snapshots
ls -1 | sort | head -n -7 | while read -r old; do
btrfs subvolume delete "$old"
done
```
```bash [Terminal]
sudo chmod +x /usr/local/bin/btrfs-snapshot.sh
```
```bash [Terminal]
sudo nano /etc/systemd/system/btrfs-snapshot.service
```
```ini [btrfs-snapshot.service]
[Unit]
Description=Take a Btrfs root snapshot
[Service]
Type=oneshot
ExecStart=/usr/local/bin/btrfs-snapshot.sh
```
```bash [Terminal]
sudo nano /etc/systemd/system/btrfs-snapshot.timer
```
```ini [btrfs-snapshot.timer]
[Unit]
Description=Daily Btrfs root snapshot
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
```
```bash [Terminal]
sudo systemctl daemon-reload
sudo systemctl enable --now btrfs-snapshot.timer
```
Vérifiez qu'il est bien planifié avec `systemctl list-timers`, et déclenchez-en un tout de suite pour tester avec `sudo systemctl start btrfs-snapshot.service`.
Et voilà : un bouton annuler automatique et permanent pour votre serveur, qui tourne tranquillement à côté des vraies sauvegardes que Backrest prend déjà hors site.
Et voilà : un bouton annuler automatique et permanent pour votre serveur, qui encadre discrètement chaque mise à jour et se nettoie tout seul, en tournant à côté des vraies sauvegardes que Backrest prend déjà hors site.