7.1 KiB
title, description
| title | description |
|---|---|
| BTRFS Snapshots | Format Debian's root filesystem with BTRFS and use snapshots to instantly roll back a risky update or config change, as a local complement to Backrest's off-site 3-2-1 backups. |
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
BTRFS is a Linux filesystem with one killer feature for a homelab: snapshots. A snapshot freezes the exact state of a filesystem in an instant, at essentially zero cost, without copying a single byte of data upfront. Break something ten minutes after an apt full-upgrade, or overwrite the wrong .env file, and you can go back to exactly how things were before, without touching a backup at all.
This is not what Backrest and the 3-2-1 rule are for, so it's worth being precise about the difference before setting anything up.
Snapshots are not backups
A snapshot lives on the exact same disk as the data it protects. It's instant, needs no network, and it's perfect for undoing a mistake you just made, but it does nothing at all the day that disk itself dies, gets stolen, or your server burns down. That's what a real 3-2-1 backup is for: a copy on different media, ideally off-site.
Think of it this way:
- Snapshot = an undo button. Instant, local, cheap, only useful while the disk is alive.
- Backup = insurance. Slower, off-site, the only thing that survives the disk itself failing.
Keep both. Snapshots make you fearless about updates and experiments, backups make sure a dead drive stays an inconvenience instead of a catastrophe.
::note{to="/serveex/core/installation#partitioning"}
This guide assumes the root partition was formatted with Btrfs during Debian's installation. Btrfs can't be safely bolted onto an existing ext4 root after the fact, so this is a choice you make once, at install time. ::
Formatting the root partition with BTRFS
Debian's Guided partitioning only ever offers ext4. To get Btrfs, pick Manual partitioning instead, at the same step the main install guide describes:
::steps{level="3"}
Select Manual partitioning
At the partitioning method screen, choose Manual instead of Guided - use entire disk.
Create a partition table
Select the disk, confirm creating a new empty partition table, then select the resulting FREE SPACE and choose Create a new partition.
Set the partition size and type
Give the partition the rest of the disk (minus a small EFI partition if you're on UEFI, handled the same way as a Guided install), and set Use as to Btrfs journaling file system, with the mount point /.
Finish partitioning
Finish partitioning and write changes to disk, then confirm with Yes.
Done!
::
Everything else in the installer stays the same.
Taking a snapshot
A snapshot is created with a single command, and completes instantly no matter how much data is on the disk, since Btrfs only starts copying blocks the moment something actually changes (copy-on-write):
sudo mkdir -p /.snapshots
sudo btrfs subvolume snapshot -r / /.snapshots/$(date +%F_%H-%M-%S)
-rmakes it read-only, which is what you want for a safety net: nothing, including you by accident, can modify a snapshot after the fact.- Storing snapshots under
/.snapshotskeeps them out of the way, and Btrfs is smart enough not to recurse into a subvolume the next time you snapshot/itself, so snapshots never end up containing older snapshots.
Take the habit of running this before anything that could go wrong: sudo apt full-upgrade, editing a systemd unit, or a Docker Compose change that touches something outside /srv/docker.
::tip
✨ Give the snapshot a name that means something instead of just a timestamp, for example /.snapshots/before-upgrade-2026-09-09, so you know why it's there when you find it three weeks later.
::
Restoring files from a snapshot
A snapshot is just a folder: everything the filesystem looked like at that instant, browsable like any other directory.
ls /.snapshots/2026-09-09_18-30-00/etc/ssh/
To undo a mistake, copy the file (or folder) back from the snapshot over the current one:
sudo cp -a /.snapshots/2026-09-09_18-30-00/etc/ssh/sshd_config /etc/ssh/sshd_config
-a preserves permissions and ownership, which matters for anything under /etc.
::note
This covers the vast majority of real homelab accidents: a bad config, a deleted file, a package upgrade that broke one thing. Rolling back the entire root filesystem (for a system that no longer boots at all) is also possible, by renaming subvolumes from a live USB, but it's a more delicate, less common operation. The Btrfs documentation covers it if you ever need it, and honestly, if it comes to that, this is exactly the scenario your off-site Backrest backup is for anyway. ::
Managing snapshots
sudo btrfs subvolume list /
Lists every subvolume on the filesystem, snapshots included, each with its own ID. Delete one you no longer need with:
sudo btrfs subvolume delete /.snapshots/2026-09-09_18-30-00
::caution
Snapshots are cheap, not free: the moment the live filesystem diverges from a snapshot, the old blocks stick around for as long as the snapshot references them. A pile of old snapshots on a server that changes a lot (container images, logs) can quietly eat real disk space. Check with df -h / and prune what you don't need anymore.
::
Automating snapshots
Rather than remembering to run the command by hand, a small script plus a systemd timer takes one automatically and prunes old ones:
sudo nano /usr/local/bin/btrfs-snapshot.sh
#!/bin/bash
set -e
mkdir -p /.snapshots
btrfs subvolume snapshot -r / "/.snapshots/$(date +%F_%H-%M-%S)"
# Keep only the 7 most recent snapshots
cd /.snapshots
ls -1 | sort | head -n -7 | while read -r old; do
btrfs subvolume delete "$old"
done
sudo chmod +x /usr/local/bin/btrfs-snapshot.sh
sudo nano /etc/systemd/system/btrfs-snapshot.service
[Unit]
Description=Take a Btrfs root snapshot
[Service]
Type=oneshot
ExecStart=/usr/local/bin/btrfs-snapshot.sh
sudo nano /etc/systemd/system/btrfs-snapshot.timer
[Unit]
Description=Daily Btrfs root snapshot
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now btrfs-snapshot.timer
Check it's scheduled with systemctl list-timers, and trigger one right away to test it with sudo systemctl start btrfs-snapshot.service.
That's it: a rolling, automatic undo button for your server, running quietly alongside the real backups Backrest is already taking off-site.