Experiences with zfs-autobackup on TrueNAS SCALE?

Hi,

  1. What is your usage experience with this tool on TrueNAS - any errors, instabilities or other issues, which directly affected TrueNAS appliance?
  2. What would be the preferred way to install this pip package?

RE 1.: I got a bit concerned, after having read over Correct way to script ZFS replication in TrueNAS Scale?, esp. TrueNAS GUI error in Correct way to script ZFS replication in TrueNAS Scale? - #33 by Mastakilla. Any clarification would be great.

RE 2.: A guide is at HowTo: Using ZFS Autobackup with Scale | TrueNAS Community , but python3 -m venv seems not available in current SCALE versions 24/25? I think, it could make sense to create a python -m zipapp self-executable zfs-autobackup.pyz to pack the app with its dependencies, so there is no need for venv.

@sfatula As you created a couple posts about this tool: Still satisfied with it? (Hopefully it’s OK to tag you here)


Post-note:
Built-in TrueNAS periodic snaphot and replication task is not flexible enough for my case. Hence I’d be interested in experiences specifically with zfs-autobackup on a TrueNAS SCALE 24/25 system, which in my view can substitute all TrueNAS tasks best, with no need to be installed.

In the end, I managed to get it all working fine and I’ve been happy with how it’s been running ever since…

These are my notes on how to install / upgrade ZFS Autobackup:

	https://www.truenas.com/community/threads/howto-using-zfs-autobackup-with-scale.112454/
	https://github.com/psy0rz/zfs_autobackup
	
	cd /mnt/backup-pool/homedir-ds/home/root/bin
	wget https://github.com/psy0rz/zfs_autobackup/archive/refs/heads/master.zip
	unzip master.zip
	rm master.zip
	mv zfs_autobackup zfs_autobackup.old_$(date +"%Y-%m-%d_%H-%M")
	mv zfs_autobackup-master zfs_autobackup
	cd zfs_autobackup
	python -m venv autobackup-venv --without-pip --system-site-packages
	source autobackup-venv/bin/activate
	curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
	python get-pip.py
	pip install -r requirements.txt
	deactivate
	VERSION="$(autobackup-venv/bin/python -m zfs_autobackup.ZfsAutobackup --version | awk -F' v' '{print $2}' | awk '{print $1}')"
    echo "Installation of zfs_autobackup ${VERSION} completed successfully"

You can find the script that I’m using for my personal / very specific backup-need here:

Very very satisfied, much better than built in replication for a variety of reasons. Sorry, am in Bali so not a lot of time to add more notes. Been using it at least a year and never had to start over, handles any communication errors, seamless picking of datasets to backup, etc.

I have no experience with the following, and cannot vouch for it. On the surface it looks clean and usable. It offers a stub script to defer actual operation inside Docker. (Well, it uses Podman. But that’s easily changed.)

Or you could get fancyfancy and try something like this.

touch ./zfs-autobackup
docker run --rm -v ./zfs-autobackup:/zfs-autobackup python:slim bash -c \
    'pip install shiv ; shiv -c zfs-autobackup -o zfs-autobackup zfs-autobackup'

@Mastakilla Thanks for handing in your notes. I just re-checked the commands and discovered, pip args make a difference on TrueNAS system:

  • python3 -m venv autobackup-venv --without-pip --system-site-packages works
  • python3 -m venv autobackup-venv errors with The virtual environment was not created successfully..., surprisingly still creates venv directory.

I’ll try to create a self-executable single file archive for zfs-autobackup, so step of manually downloading pip is not needed.

@sfatula This is what I wanted to read - and confirms my own impression of this great tool!

@jct I have the unpopular opinion to use NAS as plain storage without VMs/Container, so Docker isn’t possible in my case. Still idea is appreciated.

To use the two-line build you’d momentarily select an apps directory to enable Docker, then deselect/disable them both when you’re done.

I guess to have found an easier route than pip or Docker:

git clone https://github.com/psy0rz/zfs_autobackup
python3 -m zipapp zfs_autobackup/\
  -o zfs_autobackup.pyz\
  -p "/usr/bin/env python3"\
  -m 'zfs_autobackup.ZfsAutobackup:cli'

This creates a Python self-executable, single file zfs_autobackup.pyz, which can be copied over to TrueNAS machine. (zfs-autobackup does not have required third party runtime dependencies.)

Then on TrueNAS just execute this file:

# ./zfs_autobackup.pyz

This properly invoked above command on my test system and displayed help message. Now I need to figure out, how and what command parameters to use.

Cool! Does this bundle all relevant dependencies like the shiv build did, or does it only gather its own, releasing any external modules into the user’s home environment?

Can’t speak about that mentioned shiv build, but:

Above command should contain all zfs-autobackup Python modules in the file zfs_autobackup.pyz.zfs-autobackup itself does not have any required external dependencies: argparse is already included in standard library for half recent Python versions and colorama is only for colored CLI output - if not installed, there is a fallback to normal output.

If you still need this external dependency, you should be able to do something like:

python -m pip install\
  -r zfs_autobackup/requirements.txt\
  --target zfs_autobackup/

, before executing above -m zipapp command again (not tested). But for normal batch usage, this should not be necessary, so keep things simple :slight_smile: .

Ah — good. So my self-contained build offers colorization, and your self-contained build doesn’t borrow Docker to get there. I’ll take it; cheers! :beers:

@jct Yeah kinda. As said, you can add dependencies, if needed:

git clone https://github.com/psy0rz/zfs_autobackup

# download deps via venv and place them at top-level of later .pyz archive root dir
# (venv can be deleted after zfs_autobackup_all.pyz creation)
python3 -m venv venv
. venv/bin/activate
python -m pip install -r zfs_autobackup/requirements.txt --target zfs_autobackup/
deactivate

# create self-executable incl. deps
# (zfs_autobackup dir can be deleted after zfs_autobackup_all.pyz creation)
python3 -m zipapp zfs_autobackup/\
  -o zfs_autobackup_all.pyz\
  -p "/usr/bin/env python3"\
  -m 'zfs_autobackup.ZfsAutobackup:cli'

# copy over zfs_autobackup_all.pyz to TrueNAS, then 
./zfs_autobackup_all.pyz --help # should work

This should include zfs-autobackup and all its dependencies in a single file zfs_autobackup_all.pyz, which can be executed on TrueNAS system.

@Mastakilla Regarding Correct way to script ZFS replication in TrueNAS Scale? - #34 by Mastakilla : Did you manage to use --clear-mountpoint , as suggested? Is it safe to use for TrueNAS?

Update: I guess questions about --clear-mountpoint are wrong in the first place:

If using an external tool for snapshots and replication, we should strive to be as close as possible to ZFS properties set by TrueNAS, when initiating a replication task and creating target datasets. TrueNAS uses canmount=on, so that’s gonna be the proper setting.

Probably it is best to let TrueNAS create all datasets itself (by GUI replication task and run it once), and then use zfs-autobackup on these existent datasets. Everything is working for me, when doing this.

If letting zfs-autobackup create target datasets for replication, I get all errors from zfs_autobackup and TrueNAS compatibility issues with mounted datasets · Issue #254 · psy0rz/zfs_autobackup · GitHub as well. I’d imagine that TrueNAS has its own application state about datasets and of course assumes to initiate everthing itself - hence errors about unknown user/group quota etc.

To give a review, zfs-autobackup is quite awesome.

I switched some of my dataset backups to it for flexibility - no problems so far, tool makes a stable and well-thought-out impression.

If you intend to do replication with zfs-autobackup, I strongly recommend to create the replication dataset via TrueNAS GUI/task, so appliance is aware of this dataset and initiates all expected ZFS properties. Afterwards snapshots can be created, replicated and cleaned up as needed.

Here is an example script template for snapshot creation on main + clean up + replication to tank:

zfs_autobackup --verbose --debug --allow-empty \
  --exclude-received --rollback --zfs-compressed \
  --keep-source=10,1d1w,1w1m,1m1y --keep-target=10,1d1w,1w1m,1m1y \
  --strip-path=1 --snapshot-format={}-%Y-%m-%d_%H-%M --no-progress \
  --clear-refreservation --destroy-missing=30d main tank

Hello, I’m the author of zfs-autobackup-docker, the container image @jct mentioned earlier. This thread and a poke by psy0rz made me sit down with a TrueNAS instance and figure out a proper way to run zfs-autobackup there, here’s what came out of it.

First I added an opt-in service mode: CRON_SCHEDULE makes the container stay up and run zfs-autobackup on that schedule. This is needed because TrueNAS Apps only know long-running containers.

And there is a ready-made compose file for a TrueNAS Custom App: truenas/docker-compose.yaml. Setup is:

  1. The dataset the backups are received under needs to exist on the ssh target already, zfs-autobackup does not create it: zfs create -p backup/truenas there
  2. Create a config-dataset for the app’s state (ssh key, known_hosts), e.g. tank/apps/zfs-autobackup
  3. Edit the settings block at the top of the docker-compose.yaml: backup name, datasets to back up, ssh target, config-dataset, etc.
  4. Apps → Discover Apps → ⋮ (top right) → Install via YAML, paste, install.
  5. On the first start the app generates an ssh key and prints the public key in the logs (“View logs” of zfs-autobackup-init); the first backup run fails because the target doesn’t trust it yet. Add it to authorized_keys on the target, then restart the app: the backup runs again immediately and the logs show whether it works.

Nothing lives on the root filesystem. TrueNAS upgrades don’t touch it, no venv/pip dance.

For more details (e.g. healtchecks, failure notifications, security) see the TrueNAS section in the README.

I also submitted this as a proper catalog app truenas/apps#5685 with a nice form instead of a YAML file but iX declined because it accesses ZFS directly without coordination with the TrueNAS middleware.

What “without coordination” means in practice (tested on 25.04 and 25.10):

  • The app runs as root with CAP_SYS_ADMIN on /dev/zfs: full control over all datasets.
  • zfs-autobackup’s snapshots show up in the UI like any other
  • Periodic snapshot tasks by TrueNAS on the same datasets are fine, each tool only thins its own naming scheme.
  • The newest zfs-autobackup snapshot on each side carries a hold to protect the last common snapshot between the source and target; deleting it in the UI fails with “dataset is busy”.
  • The compose file passes --exclude-received, which tells zfs-autobackup to ignore datasets where the autobackup: property was received and only use the ones where it was set locally. The reason: when ZFS replicates a dataset it copies its properties too, including autobackup:<name>=true. A copy that a TrueNAS replication task makes of a dataset you selected for zfs-autobackup (e.g. tank/photos → backuppool/photos) would otherwise be marked for backup as well; zfs-autobackup would snapshot and hold the copy, and the TrueNAS replication task that owns it can then fail with “dataset is busy” as soon as it has to remove a snapshot that is held (its retention pruning the copy, or a rollback before an incremental receive). The same would happen when another machine running zfs-autobackup with the same backup name is replicated into this TrueNAS. With the flag, both cases just work.

Feedback and issue reports are always appreciated! Curious to hear if this works for you.