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.
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 🙂.
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.
mkdir /run/btr_pool
.mount /dev/sdb2 /run/btr_pool
cp /etc/btrbk/btrbk.conf.example ~/.btrbk.conf
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
sudo btrbk -c ~/.btrbk.conf -v -n run
for a dry-run and without the -n
flag to stop dry-running.sudo btrbk -c ~/.btrbk.conf -l debug run
to debug the config.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
touch /usr/bin/run_btrbk.sh
.chmod +x /usr/bin/run_btrbk.sh
.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
sudo systemctl status philsBtrbk.service
to see if the service works.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
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
/dev/sdb2/
at /run/btr_pool/
at startup, I edit /etc/fstab
and add to the bottom of the fileUUID={YOUR_DISK_ID} /run/btr_pool btrfs defaults 1 2
/etc/fstab
is configured correctly by running mount -a
. Be careful, messing up the fstab file will potentially prevent a machine from booting.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: