Automating Backups With Btrbk On Fedora 34

January 14, 2022

Back in 2019, I wrote an article discussing core-principles of creating backups on a Linux machine. Ever since I wrote that piece, I refined my setup. My setup is built around a computer storage format called btrfs, which is based on the data structure of a copy-on-write B-Tree. That data structure makes generating snapshots a byproduct of storing data.

Schema Btrbk Backups

I leverage the great btrbk to manage snapshots with a systemd timer unit. I like the way btrbk creates, deletes and copies the snapshots for me. I also like the systemd timer unit. The setup works really well for my purpose.

Now, this is not intended to be a step-by-step guide for setting up btrbk. This comes without any strings attached. Backups are really important, and if I were you and you had any critical data on your disk, I wouldn't trust a random blog post on how to set things up. This started out as my private documentation for how I set up my backup schedule. If it ends up helping you, dear unknown reader, that's great. But don't expect this to work and/or any support 🙂.

Basics Without btrbk

To creat a quick backup of my /home folder, I run

btrfs subvolume snapshot -r /home /.snapshots/home-1

and create the /.snapshots/ directory beforehand. To test the capabilities of the snapshot, I run

touch ~/file.txt
btrfs subvolume snapshot -r /home /.snapshots/home-2

and then I navigate into /.snapshots/. The home-1/ directory doesn't contain file.txt, whereas the file home-2/file.txt exists. I like how easy this is. I don't need to mount a container, go through a list of archives and jump through hoops to access my backup. Everything is available on the disk, and I can access it immediately.

The next step of backing up data is sending snapshots to an external drive. I don't want all my backups to sit on one drive, because if that drive fails or the house burns, my data is gone. I expect there to be an external drive mounted at /run/media/user/disk.

mkdir /run/media/user/disk/bk
sudo btrfs send /.snapshots/home-day1 | sudo btrfs receive /run/media/user/disk/bk

Great! I just sent a snapshot to an external drive. To set up incremental snapshots on the external drive, I run

sudo btrfs send -p /.snapshot/home-day1 /.snapshot/home-day2 | sudo btrfs receive /run/media/user/mydisk/bk

and the next day

sudo btrfs subvolume snapshot -r /home /.snapshots/home-day3
sudo btrfs send -p /.snapshot/home-day2 /.snapshot/home-day3 | sudo btrfs receive /run/media/user/mydisk/bk

Which is a low-key, manual version of what btrbk does. Next, I'll automate this. Also, see this article for where I go my inspiration form.

Automation With btrbk

  1. Install btrbk.
  2. mkdir /run/btr_pool.
  3. mount /dev/sdb2 /run/btr_pool
  4. cp /etc/btrbk/btrbk.conf.example ~/.btrbk.conf
  5. That config file looks like this for me:
transaction_log            /var/log/btrbk.log

stream_buffer              512m


# keep all snapshots for 2 days, no matter how frequently you (or your cron job) run btrbk
# keep daily snapshots for 14 days (very handy if you are on the road and the backup disk is not attached)
# keep monthly backups forever
# keep weekly backups for 10 weeks
# keep daily backups for 20 days

timestamp_format        long
snapshot_preserve_min   2d
snapshot_preserve       14d

target_preserve_min     no
target_preserve         20d 10w *m

archive_preserve_min    latest
archive_preserve        12m 10y

# Backup to external disk mounted on /run/media/philipp/phils-disk/btr_backup
volume /run/btr_pool

  snapshot_dir      _btrbk_snapshots
  target            /run/media/philipp/phils-disk/btrbk_backup
  subvolume         home
  subvolume         root

  # no action if external disk is not attached
  snapshot_create  ondemand



  # subvolume  kvm
  #   # use different retention policy for kvm backups
  #   target_preserve     7d 4w
  1. Run btrbk with sudo btrbk -c ~/.btrbk.conf -v -n run for a dry-run and without the -n flag to stop dry-running.
  2. If necessary, use sudo btrbk -c ~/.btrbk.conf -l debug run to debug the config.
  3. Once the btrbk CLI runs without an error, create a service. To do so, run nvim /etc/systemd/system/philsBtrbk.service and write into it:
# This service runs btrbk hourly to create new snapshots
# of my entire machine. These are then stored on the
# laptop's drive at /run/btr_pool/_btrbk_snapshots/,
# and on my external harddrive, which mounts to
# /run/media/philipp/$drive_name/btrbk_backup

# I used this article as a reference to create the config:
# https://opensource.com/article/20/7/systemd-timers

[Unit]
Description=Creates snapshots of the btrfs filesystem
Wants=philsBtrbk.timer

[Service]
Type=oneshot
ExecStart=/usr/bin/run_btrbk.sh

[Install]
WantedBy=multi-user.target
  1. touch /usr/bin/run_btrbk.sh.
  2. chmod +x /usr/bin/run_btrbk.sh.
  3. nvim /usr/bin/run_btrbk.sh and copy the following into it:
#!/bin/bash

# I use this script for philsBtrbk.service managed
# by systemd. For more details, run
# `systemctl list-timers`
sudo btrbk -c /home/philipp/.btrbk.conf run
  1. Run sudo systemctl status philsBtrbk.service to see if the service works.
  2. nvim /etc/systemd/system/philsBtrbk.timer and copy the following into it:
# This runs the snapshotting for my filesystem with btrbk
# hourly.

[Unit]
Description=Creates a snapshot and stores it on my external drive
Requires=philsBtrbk.service

[Timer]
Unit=philsBtrbk.service
OnCalendar=*-*-* *:00:00

[Install]
WantedBy=timers.target
  1. Run thhese commands
systemctl daemon-reload
systemctl start philsBtrbk.timer
systemctl enable --now philsBtrbk.timer

to start and enable the timer. To check if the timer really works, use sytemctl list-timers all.

mount /dev/sdb2 /run/btr_pool

  1. To mount /dev/sdb2/ at /run/btr_pool/ at startup, I edit /etc/fstab and add to the bottom of the file
UUID={YOUR_DISK_ID} /run/btr_pool		  btrfs	  defaults	  1 2
  1. I test that /etc/fstab is configured correctly by running mount -a. Be careful, messing up the fstab file will potentially prevent a machine from booting.

Final Thoughts

That's it. Maybe this is helpful to someone out there. Feel free to contact me if you want to add anything or comment. These are the resources I used to get going:


Profile picture

By Philipp Jung, a data engineer with one foot still in academia. Follow me on mastodon.world/@pljung, or reach out on LinkedIn.