Creating BTRFS Disk Snapshots
The following shows two alternate ways to be performing BTRFS snapshots on a NixOS system.
First - a look at how the disk is setup:
# /etc/fstab
/dev/disk/by-uuid/1234567890-abcdef-0987654321-fedcba /home btrfs subvol=home/active,compress=zstd,noatime 0 0
# /etc/nixos/hardware-configuration.nix
fileSystems."/home" =
{ device = "/dev/disk/by-uuid/1234567890-abcdef-0987654321-fedcba";
fsType = "btrfs";
options = [ "subvol=home/active" "compress=zstd" "noatime" ];
};
Need to add another subvolume to store the snapshots
# /etc/nixos/hardware-configuration.nix
fileSystems."/home/.snapshots" =
{ device = "/dev/disk/by-uuid/1234567890-abcdef-0987654321-fedcba";
fsType = "btrfs";
options = [ "subvol=home/snapshots" "compress=zstd" "noatime" ];
};
Snapper
Written in C++ and supported by the SUSE Linux Team
Snapper requires you to have snapshots in a subvolume folder called .snapshots
on the same mount point you are snapshotting. Make sure you create a folder manually before switching to this configuration.
This will create 24 hourly snapshots, 10 daily, 4 weekly, 12 monthly, and 10 yearly.
# /etc/nixos/configuration.nix
services = {
snapper = {
configs = {
home = {
SUBVOLUME="/home";
SPACE_LIMIT="0.5";
FREE_LIMIT="0.2";
BACKGROUND_COMPARISON=true;
TIMELINE_CREATE=true;
TIMELINE_CLEANUP=true;
TIMELINE_MIN_AGE="1800";
TIMELINE_LIMIT_HOURLY="24";
TIMELINE_LIMIT_DAILY="10";
TIMELINE_LIMIT_WEEKLY="4";
TIMELINE_LIMIT_MONTHLY="11";
TIMELINE_LIMIT_YEARLY="10";
EMPTY_PRE_POST_CLEANUP=true;
EMPTY_PRE_POST_MIN_AGE="1800";
};
};
};
};
BTRBK
Documentation | Source Repository
Flexible tool that offers more flexibility on naming, mounts, and targets than snapper. Written in Perl.
This will create 48 hourly snapshots, 10 daily, 4 weekly, 12 monthly, and 10 yearly, and snapshots will be labelled by volume name date and time eg home.202300609T010000
.
# /etc/nixos/configuration.nix
{
services.btrbk.instances."btrbk" = {
onCalendar = "*-*-* *:00:00";
settings = {
timestamp_format = "long";
snapshot_preserve_min = "2d";
preserve_day_of_week = "sunday" ;
preserve_hour_of_day = "0" ;
target_preserve = "48h 10d 4w 12m 10y" ;
volume."/home" = {
snapshot_create = "always";
subvolume = ".";
snapshot_dir = ".snapshots";
};
};
};