Skip to content

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:

  1. Source Pool - The pool containing data to backup
  2. 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

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:

~/.cache/zfs-backup/backup-state.json

This file contains:

  • Current operation
  • Completed stages
  • Stage timings
  • Snapshot names

Clearing State

If you need to clear the resume state:

rm ~/.cache/zfs-backup/backup-state.json

Troubleshooting

Permission Denied

If you see permission errors, ensure you're running with sudo:

sudo zfs-backup

Or configure ZFS Delegation.

Pool Not Found

If your external drive's pool isn't detected:

  1. Ensure the drive is connected
  2. Run with sudo for pool scanning
  3. Check if the pool needs to be imported manually:
    sudo zpool import
    

Sync Already in Progress

If you see "already target of a zfs receive process":

  1. Wait for the existing process to complete, OR
  2. Kill the existing process:
    sudo pkill -f "zfs receive"
    

Made with ❤ by Kartoza | Donate! | GitHub