Configuration¶
This guide covers configuration options for Kartoza ZFS Backup Tool.
Pool Structure¶
The tool works with any ZFS pool structure. When you run a backup, you'll be prompted to select:
- Source Pool - The pool containing data to backup
- Destination Pool - The external backup pool
Example Structures¶
All child datasets of the source pool are backed up — including application-managed datasets without a regular mountpoint (for example atuin). Every dataset on the destination is namespaced by the source machine's hostname so multiple hosts can share one backup drive without colliding.
Source Pool (NIXROOT) on host "abyss":
├── NIXROOT/home ← Backed up
├── NIXROOT/atuin ← Backed up (no mountpoint, still included)
├── NIXROOT/nix ← Backed up
├── NIXROOT/overflow ← Backed up
└── NIXROOT/root ← Backed up
Destination Pool (NIXBACKUPS):
└── NIXBACKUPS/abyss/
├── NIXBACKUPS/abyss/home
├── NIXBACKUPS/abyss/atuin
├── NIXBACKUPS/abyss/nix
├── NIXBACKUPS/abyss/overflow
└── NIXBACKUPS/abyss/root
Legacy flat layout¶
Older versions wrote some datasets to a flat path such as NIXBACKUPS/home. At the start of every backup the tool checks the destination pool for any flat-layout datasets that match the source pool's children and atomically renames each one into the hostname namespace (zfs rename NIXBACKUPS/home NIXBACKUPS/<hostname>/home). If a dataset exists at both the flat and the namespaced location the migration aborts with an error and the backup stops, so existing snapshots are never silently merged or destroyed — resolve the conflict by hand (typically by zfs destroy-ing whichever copy you do not want to keep) and re-run.
Encryption¶
Recommended Setup¶
We recommend using ZFS native encryption for backup pools:
# Create encrypted pool (done via "Prepare Backup Device" menu)
zpool create \
-O encryption=aes-256-gcm \
-O keyformat=passphrase \
-O keylocation=prompt \
-O compression=zstd \
-O atime=off \
NIXBACKUPS /dev/sdX
Encryption Properties¶
| Property | Value | Description |
|---|---|---|
| encryption | aes-256-gcm | Strong authenticated encryption |
| keyformat | passphrase | Password-based key |
| keylocation | prompt | Ask for password on load |
Retention Policy¶
Local Snapshots¶
By default, the tool keeps the last 7 snapshots on your local system. Older snapshots are converted to bookmarks.
Backup Snapshots¶
The backup retention policy keeps:
- All recent snapshots
- Monthly snapshots for the last 3 months
Customizing Retention¶
Currently, retention policies are hardcoded. Future versions will support configuration via:
- Command-line flags
- Configuration file
- Environment variables
CLI Mode¶
For automation and scripting, use CLI mode:
# Run incremental backup
sudo zfs-backup --backup
# Force backup (destructive)
sudo zfs-backup --force-backup
# Unmount backup disk
sudo zfs-backup --unmount
# Show help
zfs-backup --help
Environment Variables¶
| Variable | Description |
|---|---|
ZFS_BACKUP_SOURCE | Default source pool (future) |
ZFS_BACKUP_DEST | Default destination pool (future) |
Systemd Integration¶
Creating a Backup Service¶
# /etc/systemd/system/zfs-backup.service
[Unit]
Description=ZFS Backup
After=local-fs.target
[Service]
Type=oneshot
ExecStart=/usr/bin/zfs-backup --backup
StandardInput=tty
TTYPath=/dev/tty1
[Install]
WantedBy=multi-user.target
Creating a Timer¶
# /etc/systemd/system/zfs-backup.timer
[Unit]
Description=Run ZFS backup weekly
[Timer]
OnCalendar=weekly
Persistent=true
[Install]
WantedBy=timers.target
Interactive Password
The backup requires an encryption password. For fully automated backups, consider using a keyfile instead of passphrase.
Logging¶
The tool maintains a state file for resume functionality:
This file contains:
- Current operation
- Completed stages
- Stage timings
- Snapshot names
Clearing State¶
If you need to clear the resume state:
Troubleshooting¶
Permission Denied¶
If you see permission errors, ensure you're running with sudo:
Or configure ZFS Delegation.
Pool Not Found¶
If your external drive's pool isn't detected:
- Ensure the drive is connected
- Run with sudo for pool scanning
- Check if the pool needs to be imported manually:
Sync Already in Progress¶
If you see "already target of a zfs receive process":
- Wait for the existing process to complete, OR
- Kill the existing process: