I wont be adding restic commands as it is working just fine for regular backups, but I am searching for idea/way how to backup my use-case. By the way, this is a home server, don’t have features like disk array and second host or anything enterprise level. Even if you have no idea about topic, it might be worth reading, you might learn something new about jails and zfs, while you can skip to TLDR.
I am using FreeBSD feature called jails, a very old and mature feature (25 years in production), that you can, for the sake of understanding compare with docker but with internal file system fully exposed to a host - it is just a sub-directory (in my case zfs fs).
The jails reside within /usr/jails/jail-name (will use jail-name test in all further explanation) where the root of a jail is. So /usr/jails/test/etc, /usr/jails/test/dev, /usr/jails/usr,…
As an optimization feature, there exists so called thin jails or read-only base jails.
Instead of actually having a full FreeBSD root inside /usr/jails/stest, a separate directory /usr/jails/base is created, that has all the system files.
The read-only zfs snapshot of base is created, and zfs clone of snapshot is made on the top of it, while the missing jail specific directories are created within the clone like /usr/local,… you get the idea.
This has several huge benefits:
- de-duplication of same system files between jails, jail size can be in range of MBs, while full system makes it in a range of GBs
- fully protected system from changes
- very fast new jail creation (no need for copying the whole base system)
- isolated jail specifics for particular jail in a clone, for example, jail that handles emails, only has postfix/dovecot binaries, mails and its configuration
- fast upgrade, all the jails are upgraded to new system version by only upgrading the base
Now, since the /usr/jails/test is a ZFS file system, which has ability to snapshot its data and as every other zfs snapshot, it is exposed trough hidden .zfs “directory” on a root of filesystem, so in this case /usr/jails/test/.zfs (actually zroot/usr/jails/test/.zfs but nvm).
The .zfs directory contains snapshots/ and its content is the exact point in time state of file system at the time we took snapshot. Since snapshots are done with copy-on-write, this action is instantaneous
Now to restic.
If I would back up /usr/jails/test with restic, this has a huge disadvantage, the base system would be transferred into backup as whole. For each jail, producing GBs of output in repository instead of MBs (100-800MB/jail vs 2-4GB/jail). Backing up of base is completely unneeded as it is fully reproducible from FreeBSD installation.
There are a few options I have:
- meticulously tracking the changes on base on each upgrade and extending exclude list appropriately - don’t like it as it is error prone
- stopping jail each and every time the backup is made, to only expose non base content, this takes time as visualized network stack needs to be tear down and reestablish making zero downtime setup impossible
- creating a snapshot of /usr/jails/test, since this doesn’t affect base jail files, the snapshot contains only the content of the jail
Now, I would prefer the third option, as it is fast, reliable and only backs up the needed files, regardless what changed in the base system.
TLDR:
What I have issue with is that I would like to make restore to original file position (disaster recovery) and for this I would need to provide restic a backup path of a snapshot (/usr/jails/test/.zfs/snapshots/last_snapshot) but store it within backup as the path snapshot was made of (/usr/jails/test) for fast recovery.
How to achieve this?