btrbk

Table of Contents

Btrbk is a backup tool for BTRFS subvolumes, taking advantage of btrfs specific capabilities to create atomic snapshots and transfer them incrementally to your backup locations. I have been using this tool in all the linux distributions i've used including Alpine Linux.

Configuration files

btrbk config file (alpine - homepc2)

The option compat busybox is required for the utility to work with Alpine Linux. The mbuffer package needs to be installed if stream_buffer option is to be used. The below configuration file is used by the btrbk backup script.

Linux Mint is the OS used by daughter earlier when this HDD was used in homepc. So this subvolume @mint is still retained in homepc2. Since the subvolumes @mint and @rescue are not used regularly, their backup policy is different.

# This file is maintained as a literate file in
# 20240317210436-btrbk.org
transaction_log            /var/log/btrbk.log
compat busybox
stream_buffer              512m
incremental                yes
lockfile                   /var/lock/btrbk.lock
snapshot_preserve_min      2d
target_preserve_min        no
target_preserve            7d 4w 12m 0y
archive_preserve_min       latest
archive_preserve           12m 0y
ssh_identity               /etc/btrbk/ssh/id_rsa
volume /mnt/btrfs
  snapshot_dir             _btrbk_snap
  snapshot_create          always
  target send-receive      /mnt/backup/_btrbk
  subvolume  @alpine
    target_preserve        7d 4w 1m 0y
  subvolume  @mint
    target_preserve        1d 1w 1m 0y
  subvolume  @rescue
    target_preserve        1d 1w 1m 0y
  subvolume  @home
  subvolume  @audio
  subvolume  @video
  subvolume  @photos
  subvolume  @docs
  subvolume  @myhome

The example configuration file comes with sample configuration and explanation for all options. This file can be viewed without comments and modified settings as follows:

cat /etc/btrbk/btrbk.conf.example |grep -v '^ *#'|grep "\S"

Configuration for hourly backup(crontab)

prabu@homepc-lm:/etc$ sudo crontab -l
# Edit this file to introduce tasks to be run by cron.
#
...
#03 * * * * /usr/local/bin/btrbk -c /etc/btrbk/btrbk_hourly.conf run
33 * * * * /usr/local/bin/btrbk -c /etc/btrbk/btrbk_hourly.conf run

Configuration for daily backup(anacron)

prabu@homepc-lm:/etc$ cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root

#current backup system in use
1       7       daily-btrbk     /usr/bin/btrbk -q -c /etc/btrbk/btrbk.conf run

Configuration for daily backup in alpine

prabu@homepc2 /e/btrbk [1]> doas cat /etc/crontabs/root
# do daily/weekly/monthly maintenance
# min   hour    day month   weekday command
*/15    *   *   *   *   run-parts /etc/periodic/15min
0   *   *   *   *   run-parts /etc/periodic/hourly
0   2   *   *   *   run-parts /etc/periodic/daily
0   3   *   *   6   run-parts /etc/periodic/weekly
0   5   1   *   *   run-parts /etc/periodic/monthly
@reboot /usr/sbin/anacron -s

prabu@homepc2 /e/btrbk> cat /etc/anacrontab
#current backup system in use
1   7   daily-btrbk /usr/bin/btrbk -q -c /etc/btrbk/btrbk.conf run⏎

Archive to external HDD

Archive in homepc

Dry run with progress:

sudo btrbk  --progress -c ~/scripts/btrbk_external_homepc.conf -n archive /mnt/backup/_btrbk/ /mnt/ext_part1/_btrbk/homepc-lm/

Actual Archive with progress:

  $sudo btrbk  --progres -c ~/scripts/btrbk_external_homepc.conf archive /mnt/backup/_btrbk/ /mnt/ext_part1/_btrbk/homepc-lm/

--------------------------------------------------------------------------------
Archive Summary (btrbk command line client, version 0.30.0)

    Date:   Sun Mar  7 10:06:48 2021

Legend:
    ++.  created directory
    ---  deleted subvolume
    ***  received subvolume (non-incremental)
    >>>  received subvolume (incremental)
    [-]  no action
--------------------------------------------------------------------------------
/mnt/backup/_btrbk/data.*
*** /mnt/ext_part1/_btrbk/homepc-lm/data.20210116
>>> /mnt/ext_part1/_btrbk/homepc-lm/data.20210207
>>> /mnt/ext_part1/_btrbk/homepc-lm/data.20210307

/mnt/backup/_btrbk/@home.*
*** /mnt/ext_part1/_btrbk/homepc-lm/@home.20210211
>>> /mnt/ext_part1/_btrbk/homepc-lm/@home.20210307

/mnt/backup/_btrbk/@.*
***  /mnt/ext_part1/_btrbk/homepc-lm/@.20210214
>>> /mnt/ext_part1/_btrbk/homepc-lm/@.20210307

Archive in onepc

Dry run with progress:

prabu@onepc-lm:~$sudo btrbk --progress -c scripts/btrbk_external_onepc.conf -n archive /mnt/backup/_btrbk/ /mnt/ext_part1/_btrbk/onepc-lm

Actual Archive run with progress:

prabu@onepc-lm:~$ sudo btrbk --progress -c scripts/btrbk_external_onepc.conf archive /mnt/btrfs/_btrbk_snap/ /mnt/ext_part1/_btrbk/onepc-lm/
--------------------------------------------------------------------------------
Archive Summary (btrbk command line client, version 0.27.1)

        Date:   Sun Mar  7 14:02:59 2021

Legend:
        ++.  created directory
        ---  deleted subvolume
        ***  received subvolume (non-incremental)
        >>>  received subvolume (incremental)
        [-]  no action
--------------------------------------------------------------------------------
/mnt/btrfs/_btrbk_snap/@.*
 *** /mnt/ext_part1/_btrbk/onepc-lm/@.20210113
 >>> /mnt/ext_part1/_btrbk/onepc-lm/@.20210207
 >>> /mnt/ext_part1/_btrbk/onepc-lm/@.20210307

Archive in alpine Linux

The following added on the client homepc

# mkdir /etc/btrbk/ssh/
# ssh-keygen -t rsa -b 4096 -f /etc/btrbk/ssh/id_rsa -C kprabuanand@gmail.com -N ""
# scp /etc/btrbk/ssh/id_rsa.pub prabu@192.168.1.3:
# btrbk  --progress archive /mnt/btrfs/_btrbk_snap/ ssh://192.168.1.3/mnt/NAS/_btrbk/homepc2

Repeated the above steps on homepc

root@homepc:~# mkdir -p /etc/btrbk/ssh
root@homepc:~# cd /etc/btrbk/ssh/
root@homepc:/etc/btrbk/ssh# ssh-keygen -t rsa -b 4096 -f /etc/btrbk/ssh/id_rsa -C kprabuanand@gmail.com -N ""

Your identification is saved in /etc/btrbk/ssh/id_rsa and the public key is saved in /etc/btrbk/ssh/id_rsa.pub.

The following added on the server(pi) In the file "/etc/ssh/sshd_config" the following entry was added under Authentication section:

pizero2W:~$ doas cat /etc/ssh/sshd_config|grep AuthorizedKeysFile
AuthorizedKeysFile	.ssh/authorized_keys

mkdir -p /root/.ssh
chmod 700 /root/.ssh
cat /home/prabu/id_rsa.pub >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys

With the above setup the archive was done using the below command.

prabu@homepc2 ~> doas btrbk --progress archive /mnt/btrfs/_btrbk_snap/ /mnt/ext_part1/_btrbk/homepc2/

backup script

The backup script below tangles to ~/.local/bin/btrbk_backup. This is symlinked to /usr/local/bin/btrbk_backup and uses this configuration file. In addition to logging the outcome to the system log, the script also triggers an visual indicator on the sway bar by sending a i3blocks signal. The visual indicator remains until the backup is in progress.

#!/bin/sh

# Configuration
INDICATOR_FILE="/tmp/btrbk_running"
I3BLOCKS_SIGNAL=5 # matches the number in $HOME/.config/i3blocks/config
BTRBK_CONFIG="/home/prabu/.config/btrbk/btrbk.conf"

send_signal() {
    pkill -RTMIN+$I3BLOCKS_SIGNAL i3blocks
}

# Log the start time
echo "btrbk backup process started."

# Create the lock file
touch "$INDICATOR_FILE"

# Signal i3blocks to refresh
send_signal

# Cleanup runs on EXIT (success or failure)
trap "rm -f \"$INDICATOR_FILE\" &>/dev/null; send_signal" EXIT

#  Run the Btrbk Job
# Use 'exec' to replace the current shell process with the btrbk process.
/usr/bin/btrbk -q -c "$BTRBK_CONFIG" run

# Log the end time
echo "btrbk backup process ended."

The above script is invoked by dcron as shown below.

@daily ID=daily-btrbk sleep 120 && /usr/local/bin/btrbk_backup 2>&1 | logger -t daily-btrbk

References

Date: 2024-03-17 Sun 21:04

Author: Prabu Anand Kalivaradhan

Created: 2026-10-11 Sun 15:24