Deployment guide

Sanoid

Overview

Sanoid is an open source, policy-driven ZFS snapshot management toolkit. You describe a retention policy (how many frequently, hourly, daily, monthly and yearly snapshots to keep) in one plain text file, /etc/sanoid/sanoid.conf. Sanoid then takes and prunes snapshots of your ZFS datasets to match, on a schedule run by systemd. Its companion tool syncoid replicates those snapshots to another dataset or machine over SSH, giving you dependable point-in-time recovery and off-host backups for ZFS.

This guide covers deploying and configuring the SecureAnyCloud Sanoid image on Ubuntu 24.04 on Azure. The image installs Sanoid 2.3.0 from the official upstream release, pinned and verified by SHA-256 and driven by systemd: sanoid.timer runs every 15 minutes and triggers sanoid.service (take snapshots) and sanoid-prune.service (prune to policy). Sanoid is a command-line toolkit with no web interface and no login.

The image is functional out of the box. A fresh VM has no spare block device, so the first boot of every VM creates a small file-backed demo ZFS pool called tank with a dataset tank/data. It applies an example policy to the pool (keep 36 hourly, 30 daily and 3 monthly snapshots). You see a real take-and-prune cycle on a single node immediately, and you get a working template to point at your own datasets.

The image is also secure by default, with no shipped credentials. Sanoid has no daemon, no listening port, no web interface and no login of its own, so this image ships no shared or default credential of any kind. When you later replicate between machines with syncoid, you add your own SSH keys. Until then, there is nothing to rotate and nothing exposed.

What you get:

  • Sanoid 2.3.0 (and syncoid, findoid) from the official upstream release, SHA-256 verified, installed to /usr/sbin
  • systemd scheduling: sanoid.timer (every 15 minutes) drives snapshot taking and pruning, with Persistent=true so a stopped VM catches up at the next boot
  • A file-backed demo ZFS pool tank created on first boot, with a tank/data dataset
  • A ready-to-run retention policy in /etc/sanoid/sanoid.conf (hourly 36, daily 30, monthly 3) with automatic snapshotting and pruning
  • syncoid for replicating snapshots to another dataset or host over SSH using your own keys
  • zfsutils-linux and the matching kernel module, so ZFS and sanoid work on first boot with no extra setup
  • 24/7 SecureAnyCloud support

Prerequisites

Before you deploy this image, make sure you have:

  • An active Azure subscription, an SSH public key, and a VNet and subnet in the target region
  • A subscription to the Sanoid listing on Azure Marketplace
  • Network Security Group rules that allow TCP 22 (admin). No product ports need to be open to the internet, because sanoid runs entirely locally and syncoid replicates over an SSH transport you configure.

Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) is ample for managing snapshots. ZFS uses RAM for its cache, so size up for large, busy pools.

1

Deploy from the Azure Portal

  • Open the Sanoid offer on the Azure Marketplace and choose Get It Now, then Create.
  • Select your subscription, resource group and region, and choose the Standard_B2s size.
  • Provide your SSH public key for the azureuser account.
  • In the Network Security Group, allow inbound TCP 22 from your admin network. Then create the VM.
2

Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:sanoid-ubuntu-24-04:default:latest
az vm create \
  --resource-group my-rg \
  --name sanoid-01 \
  --image sac1647283583153:sanoid-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard
3

First boot

On the first boot of every VM, sanoid-firstboot.service loads the ZFS kernel module, creates the file-backed demo pool tank with the tank/data dataset, writes a layout note to /root/sanoid-info.txt and enables the schedule. First boot completes in a few seconds.

4

Confirm sanoid, the policy and the demo pool

Connect over SSH as azureuser. Confirm the toolkit version, the shipped retention policy and the demo pool:

sanoid --version grep -vE '^\s*#|^\s*$' /etc/sanoid/sanoid.conf zpool status -x tank && zfs list -o name,used,avail tank tank/data

You should see sanoid 2.3.0, the [tank/data] policy (hourly 36, daily 30, monthly 3), and pool 'tank' is healthy.

5

Take snapshots per the policy

Sanoid runs on its own timer, but you can run it by hand to see it work now. This command takes snapshots per the shipped policy and then prunes any that are over retention:

sudo sanoid --cron --verbose --force-update zfs list -t snapshot -o name,used,creation -r tank/data

Sanoid takes autosnap_-prefixed snapshots of tank/data, one each of the enabled monthly, daily and hourly types on the first run, and then lists them.

6

See the retained snapshots by type

Sanoid keeps a rolling set of snapshots for each type, as your policy defines. List the snapshots and count them by type:

zfs list -t snapshot -o name -r tank/data | grep autosnap_ zfs list -t snapshot -o name -r tank/data | grep -oE '_(hourly|daily|monthly)$' | sort | uniq -c

As the timer runs over hours and days, sanoid accumulates up to 36 hourly, 30 daily and 3 monthly snapshots. It prunes anything older automatically.

7

The snapshot schedule

Snapshot taking and pruning are driven by sanoid.timer, which fires every 15 minutes. Confirm that it is enabled and see when it next runs:

systemctl is-enabled sanoid.timer
systemctl list-timers sanoid.timer --no-pager
systemctl cat sanoid.service sanoid-prune.service | grep -E 'ExecStart|Description'

sanoid.service runs sanoid --take-snapshots and sanoid-prune.service runs sanoid --prune-snapshots. The timer triggers both. Persistent=true means a VM that was deallocated over a scheduled run catches up at the next boot.

8

Snapshot your own datasets

To snapshot and prune your own ZFS datasets instead of the demo dataset, edit /etc/sanoid/sanoid.conf. Replace the [tank/data] section with your dataset paths and adjust the retention numbers. Then restart the timer. The example below is for illustration, so adapt the dataset paths and numbers to your pool:

# In /etc/sanoid/sanoid.conf, define your dataset(s) and a template:
# [mypool/important]
# use_template = production
# recursive = yes
# [template_production]
# hourly = 48
# daily = 60
# monthly = 12
# autosnap = yes
# autoprune = yes
# then apply:
sudo systemctl restart sanoid.timer
9

Replicate snapshots to another machine with syncoid

Sanoid's companion syncoid replicates snapshots to another dataset or host over SSH for real off-host backups. Confirm that it is installed:

command -v syncoid >/dev/null && echo "syncoid is installed at $(command -v syncoid)"

To replicate to a backup host, generate an SSH key on this VM, authorize its public half on the destination and then replicate. The example below is for illustration, so adapt the user, host and target dataset to your environment:

# On THIS host: create a key and copy its public half to the backup host
#
sudo ssh-keygen -t ed25519 -f /root/.ssh/id_syncoid -N ''
# authorise /root/.ssh/id_syncoid.pub on the destination, then replicate:
#
sudo syncoid tank/data backupuser@backup-host:backups/sanoid-demo

To schedule regular replication, add a syncoid command to a systemd timer or cron entry on this VM.

10

Review the layout note

First boot writes a note that describes the demo layout and handy commands. Read it:

sudo cat /root/sanoid-info.txt
11

Security recommendations

  • Sanoid runs entirely locally and opens no network port. Keep the VM's Network Security Group restricted to SSH (22) from your admin network.
  • For syncoid replication, use a dedicated SSH key with a restricted command= entry on the destination, and open SSH only to the peer.
  • The demo tank pool is file-backed for convenience. For real data, create a pool on dedicated data disks (attach Azure managed disks and zpool create on them) so snapshots have real capacity and redundancy. Then point /etc/sanoid/sanoid.conf at your datasets.
  • Keep the OS patched. The image ships fully updated with unattended security upgrades enabled.
12

Support and Licensing

Sanoid is free and open source software distributed under the GNU GPL version 3. This image bundles Sanoid unmodified, and its license governs your use of Sanoid. The complete corresponding source ships in the image at /usr/share/doc/sac/sanoid-src/.

SecureAnyCloud images include 24/7 support. If you need help deploying or configuring Sanoid on Azure, contact us.

Deploy on Azure

Find this image on the Azure Marketplace and deploy in minutes.

Need Help?

Email sales@secureanycloud.com and our team will help you get up and running.

Deploy on Azure

Launch Sanoid 2.3.0 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure