ZFS
Use datasets, snapshots, and VM disk clones for service storage.
Use ZFS when the recovery model matters: named datasets, pre-change snapshots, or fast VM disk clones.
ZFS is a storage choice, not a payload type. It can back:
- Container, binary, script, and cron service roots.
- VM service roots and VM disks.
- Yeet-managed snapshots before risky service changes.
- Shared VM image bases for faster ZFS-backed VM creates.
Use raw filesystem paths when you do not need datasets, snapshots, or clones.
Without --zfs, --service-root is an absolute filesystem path on the catch
host. With --zfs, --service-root is a ZFS dataset name.
yeet run <svc> ./compose.yml --service-root=/srv/apps/<svc>
yeet run <svc> ./compose.yml --service-root=tank/apps/<svc> --zfs
Parent datasets must already exist. If the dataset already exists or its mountpoint already contains files, catch prints a warning and deploys into it. That warning is worth reading; existing files are existing state.
For host-wide storage, yeet init --zfs and yeet host set --zfs treat the
services-root dataset as a prefix. Services under that default root, including
catch, use child datasets such as tank/apps/<svc>.
yeet.toml records the service-root intent for future deploys. If another
checkout changes the live service root, sync it back:
yeet service sync <svc>
ZFS-backed service roots get yeet-managed snapshots before risky changes. The built-in default keeps the newest 5 yeet-created snapshots, prunes snapshots older than 7 days, and runs before these events:
rundocker-updateservice-root-migration
Yeet skips first deploys because there is no prior service state to recover. Catch prunes only snapshots it created for that service. Snapshots are a safety rail, not a full backup strategy.
yeet snapshots defaults show
yeet snapshots defaults set --enabled=true --keep-last=5 --max-age=7d
yeet snapshots defaults set --events=run,docker-update --required=false
Override one service with yeet service set:
yeet service set <svc> --snapshots=off
yeet service set <svc> --snapshots=on --snapshot-keep-last=3 --snapshot-max-age=72h
yeet service set <svc> --snapshot-events=run,docker-update
yeet service set <svc> --snapshots=inherit
Snapshot-only changes do not require a service stop. Stop the service before a service-root move.
For VM payloads, the policy controls retention for manual
yeet snapshots create <vm> commands. Automatic service-root snapshot events
do not apply to VM web-run snapshot controls.
Yeet-created ZFS snapshots are recovery points for a service or VM disk. List them when you need to see what yeet can identify for a service:
yeet snapshots list
yeet snapshots list <svc>
Inspect a recovery point before relying on it. The inspect view shows the service, snapshot name, storage target, creation time, event, mode, retention state, and any comment saved with the point:
yeet snapshots inspect <svc> <snapshot>
Protect important recovery points when they should survive automatic retention pruning:
yeet snapshots protect <svc> <snapshot>
Automatic pruning skips protected recovery points. Unprotect a recovery point before removing it.
Manual recovery point flow:
yeet snapshots create <svc> --comment "before upgrade"
yeet snapshots list <svc>
yeet snapshots inspect <svc> <snapshot>
yeet snapshots protect <svc> <snapshot>
yeet snapshots unprotect <svc> <snapshot>
yeet snapshots rm <svc> <snapshot> --yes
Use clone first when you want to inspect a recovery point or copy files out
without changing the original service.
yeet snapshots clone <svc> <snapshot> <svc>-recover
yeet info <svc>-recover
Use restore when you want to roll the original service data back in place:
yeet snapshots restore <svc> <snapshot> --stop --yes
restore creates a pre-restore recovery point before it mutates ZFS state. If
the restore does not produce the result you expected, inspect the new
pre-restore point before making another change.
Snapshots recover storage state. Service generations recover deployed
definitions and install artifacts. The default --generation=current keeps
the current deployed definition while restoring data. Pass
--generation=snapshot only when the selected snapshot recorded a generation
and you also want to restore that older deployed definition.
yeet run can set the initial root for a new service. To move an existing
service root, stop the service and use yeet service set:
yeet stop <svc>
yeet service set <svc> --service-root=tank/apps/<svc> --zfs --copy
yeet service set <svc> --service-root=tank/apps/<svc> --zfs --empty
Use --copy to copy the old root into the new dataset, or --empty to create
a new empty root. yeet service set leaves the old root in place until you
decide the migration is good.
For VMs, --zfs lets yeet prepare the VM disk on a ZFS-backed service root:
yeet run <vm> vm://ubuntu/26.04 --service-root=tank/vms/<vm> --zfs
The first VM created on a pool for an image family/version prepares a shared ZFS image base. Later VMs on the same pool and image family/version clone that base instead of writing the root filesystem again.
When a newer VM image enters the cache, yeet keeps ZFS image bases that VM
clones still use and prunes only old unreferenced bases. Use
yeet vm images prune --dry-run to inspect cleanup before removing anything.
Stop a ZFS-backed VM before growing its disk:
yeet stop <vm>
yeet vm set <vm> --disk=128g
yeet start <vm>
Yeet grows the VM disk and guest ext4 filesystem. Disk shrink and live resize are not supported.
yeet rm --clean <vm> removes the VM service data, VM clone, and local
yeet.toml entry. It does not remove the shared image base, so future VMs can
keep cloning it.
If ZFS is present for VM disk setup, the host also needs udevadm.
Use ZFS when you want named datasets, storage-level recovery points, or faster repeat VM creates on the same pool. Skip it for simple services where a normal filesystem path is enough.
- Data Layout shows where service files live.
- VMs covers VM-specific ZFS behavior.
- Containers, Binaries & Scripts, and Cron Jobs show payload-specific examples.
- yeet CLI lists the
--zfs, snapshot, and service-root flags.