Skip to main content

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:

Disk 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

Source Repository

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";
      };
    };
  };