Onsite backups with zrepl
For some time I've been using a homegrown solution for onsite backups. It works fine, but required me to manually prune old snapshots periodically. Rather than extend my script to support pruning, I decided to use a prebuilt solution.
zrepl is a tool that handles periodic snapshotting, sending snapshots to other zpools (possibly remote), and pruning old snapshots. It does exactly what I needed, and more.
Installation
For Arch Linux users, a package for zrepl is available in the AUR. For other distributions, see the documentation.
cd aur
auracle download -r zrepl
cd zrepl
less PKGBUILD # Always inspect AUR packages!
makepkg -sic
Configuration
On my system, I have my root filesystem in the dataset zroot/ROOT/default
, a HDD-backed zpool named slow
, and a dataset containing lectures and other large media files at slow/bulk
. I configured zrepl to back up the root dataset to slow/zrepl
and take a daily snapshot of slow/bulk
.
# /etc/zrepl/zrepl.yml
global:
logging:
- type: syslog
format: human
level: warn
jobs:
# Periodically send a snapshot of the root filesystem to slow/zrepl.
- name: zroot_to_slow
type: push
connect:
type: local
# Must match listener_name from sink below.
listener_name: slow_zrepl_sink
# A name for the system being backed up. I called it `local` because
# there's only one system involved. The hostname would also be fine.
client_identity: local
filesystems:
"zroot/ROOT/default": true
snapshotting:
type: periodic
prefix: zrepl_
interval: 1h
pruning:
keep_sender:
- type: not_replicated
- type: regex
# Keep snapshots not created by zrepl
negate: true
regex: "^zrepl_.*"
keep_receiver:
- type: grid
# Hourly for a day
# Daily for 6 months
# Weekly for 2 years
# Monthly for 10 years
grid: 1x1d(keep=all) | 180x1d | 104x1w | 120x30d
regex: "^zrepl_.*"
# This is the dataset where the snapshots are sent to.
- name: slow_zrepl_sink
type: sink
serve:
type: local
# Must match listener_name from push above.
listener_name: slow_zrepl_sink
root_fs: slow/zrepl
recv:
placeholder:
encryption: inherit
# Take a daily snapshot of slow/bulk.
- name: snapshot_bulk
type: snap
filesystems:
"slow/bulk": true
snapshotting:
type: periodic
prefix: zrepl_
interval: 24h
pruning:
keep:
- type: grid
# Daily for 6 months
# Weekly for 2 years
# Monthly for 10 years
grid: 180x1d | 104x1w | 120x30d
regex: "^zrepl_.*"
- type: regex
# Keep snapshots not created by zrepl
negate: true
regex: "^zrepl_.*"
Starting the service
First, create the destination dataset:
sudo zfs create -o readonly=on -o mountpoint=none slow/zrepl
Start zrepl:
sudo systemctl enable --now zrepl.service
Wait until the first snapshot is sent:
sudo zrepl status
Give the destination dataset a mountpoint so you can easily access its snapshots:
sudo zfs set mountpoint=/slow/zrepl slow/zrepl/local/zroot/ROOT/default
You should now be able to access the snapshots at /slow/zrepl/.zfs/snapshot/zrepl_YYYYMMDD_HHMMSS_000
. Note that the .zfs
directory is hidden by default, so you must navigate to it directly.