ZFS combines a robust filesystem with volume management, snapshots, and replication in one toolset. In this guide, you will deploy ZFS on Ubuntu 24.04, create an encrypted dataset, and set up automatic snapshots and offsite replication using Sanoid and Syncoid. The steps are safe for production, SEO-friendly, and easy to follow for sysadmins and power users.
What you will achieve: install ZFS, create a tuned pool, enable native encryption, configure automatic snapshots (Sanoid), and push incremental backups to another host (Syncoid). You will also learn a few health and troubleshooting commands to keep your pool in good shape.
Prerequisites
- Ubuntu 24.04 (server or desktop).
- Two or more blank disks (recommended) or one disk for testing. Use /dev/disk/by-id/... paths for stable device names.
- Root or sudo privileges on both the source and the backup host (for replication).
- SSH connectivity to a backup host if you plan to use Syncoid.
Install ZFS and useful tools
Run the following commands to install ZFS and snapshot/replication tools:
sudo apt update && sudo apt install -y zfsutils-linux sanoid mbuffer openssh-client openssh-server
Confirm the kernel module is loaded:
sudo modprobe zfs && zpool --version
Create a ZFS pool with sensible defaults
List disks by ID so device names don't change across reboots:
ls -l /dev/disk/by-id/
Example: create a mirrored pool named tank using two drives. The options below enable modern defaults like zstd compression and a 4K-friendly sector size:
sudo zpool create -o ashift=12 -O compression=zstd -O atime=off -O xattr=sa -O mountpoint=/tank tank mirror \ /dev/disk/by-id/ssd-a-id /dev/disk/by-id/ssd-b-id
If you have a single disk for testing, omit the mirror keyword. Enable periodic trim for SSDs:
sudo zpool set autotrim=on tank
Create a native encrypted dataset
ZFS native encryption protects data at rest at the dataset level. The command below creates an encrypted dataset and prompts for a passphrase:
sudo zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt -o compression=zstd tank/secure
Mount paths are created automatically under /tank. To unlock an encrypted dataset after a reboot, use:
sudo zfs load-key tank/secure && sudo zfs mount -a
Optional (auto-unlock on headless servers): store a key file with strict permissions. Understand the risk—this trades convenience for reduced physical security.
sudo mkdir -p /etc/zfs/keys && sudo chmod 700 /etc/zfs/keysecho "YOUR-LONG-PASSPHRASE" | sudo tee /etc/zfs/keys/secure.key > /dev/nullsudo chmod 600 /etc/zfs/keys/secure.keysudo zfs set keylocation=file:///etc/zfs/keys/secure.key tank/secure
Install and configure Sanoid for automatic snapshots
Sanoid provides policy-driven snapshots and pruning. Create a configuration:
sudo nano /etc/sanoid/sanoid.conf
Use this minimal but production-ready policy (adjust to your needs):
[template_production] hourly = 24 daily = 7 weekly = 4 monthly = 12 autosnap = yes autoprune = yes
[tank/secure] use_template = production recursive = yes
Enable the systemd timer so snapshots run hourly by default:
sudo systemctl enable --now sanoid.timer
You can trigger an immediate run and inspect logs:
sudo systemctl start sanoid.servicejournalctl -u sanoid.service --no-pager
Set up Syncoid for incremental replication
Install ZFS and Sanoid/Syncoid on the backup host as well. Then configure key-based SSH so the source can reach the backup host:
sudo -issh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N ""ssh-copy-id -i /root/.ssh/id_ed25519.pub backup@backup-host
Run an initial replication. Syncoid will create the destination dataset if needed and then send incremental diffs after the first run:
syncoid --recursive tank/secure backup@backup-host:tankbackup/secure
Automate replication on a schedule using systemd. Create a service:
sudo nano /etc/systemd/system/syncoid-secure.service
[Unit]Description=Replicate tank/secure to backup hostWants=network-online.targetAfter=network-online.target[Service]Type=oneshotExecStart=/usr/sbin/syncoid --recursive tank/secure backup@backup-host:tankbackup/secure
Create an hourly timer:
sudo nano /etc/systemd/system/syncoid-secure.timer
[Unit]Description=Hourly Syncoid for tank/secure[Timer]OnCalendar=hourlyPersistent=true[Install]WantedBy=timers.target
Enable it:
sudo systemctl daemon-reloadsudo systemctl enable --now syncoid-secure.timersystemctl list-timers | grep syncoid
Health checks and maintenance
- Check pool state: zpool status -v
- List datasets and snapshots: zfs list and zfs list -t snapshot
- Start a monthly scrub (data integrity check) via cron: sudo crontab -e and add 0 3 1 * * zpool scrub tank
- Monitor free space: keep pools under ~80% to maintain performance.
Troubleshooting
- Pool not importing after reboot: sudo zpool import then sudo zpool import -f tank if needed.
- Encrypted dataset locked: sudo zfs load-key tank/secure then sudo zfs mount -a.
- Replication permission errors: ensure the remote user can run ZFS commands (use root over SSH or configure sudoers for /sbin/zfs and /sbin/zpool without password).
- Disk IDs changed: always use /dev/disk/by-id/ when creating pools.
You now have a modern, encrypted ZFS setup on Ubuntu 24.04 with automatic snapshots and scheduled replication. This design gives you fast local rollbacks, versioned backups, and an offsite copy—meeting the core pillars of data protection with minimal moving parts.
Comments
Post a Comment