Certain directories within a jail can be swapped out to (datasets) "outside". This allows this data to be stored independently of the jail.
The goal, similar to Docker, is to depend as little as possible on the jail itself. This way, if the jail is corrupted or deleted for some reason, we are able to restore the previous configuration and data with minimal effort. Also, these directories can then be efficiently and regularly backed up via snapshot, which also simplifies further backups. Not to mention moves or migrations.
Last update:
work/usr/local/bastille/data/JAILNAME, which refers to the ZFS pool data in the dataset bastille_data/JAILNAME/usr/local/bastille/jails/JAILNAME/root/mnt/data123Important: Since ZFS is used here, there is a distinction between the pool or dataset and the actual directory in which the dataset is mounted
work in the directory bastille and data in the directory bastille_data. This pool may offer significantly more storage space. This is very useful for large data dumps such as images or file shares that simply have no place in the jail. Read-only if necessary.However, to prevent these different pools from causing confusion, these datasets are bundled in the Bastille directory /usr/local/bastille/.
The complete picture is as follows:
─ work/bastille -> /usr/local/bastille/
─ data/bastille_data -> /usr/local/bastille/data
└── /usr/local/bastille/jails # Jail directory
└── JAILNAME # Jail name
└── root # Root of the jails, the / within the jail
└── /usr/local/bastille/data # Jail data directory
└── JAILNAME # Jail name
└── conf # Configurations, ex. /mnt/conf
└── data # Jail data, ex. /mnt/data
└── db # Database, ex. /var/db/pgsql
└── ... # etc
But how does that work? Quite simply via NullFS. NullFS essentially places the contents of directory A in directory B, even across jail boundaries. For example, /usr/local/bastille/data/JAILNAME/data is then located in the jail under /mnt/data. Very handy! However, the correct permissions are an important factor. If there is a user USER with the ID 123 in the jail who has the appropriate access rights to a directory, then the directory outside the jail MUST have the same rights. Fortunately, the user ID is sufficient for this, so you don't have to create the corresponding user name in the FreeBSD server every time.
Everything described below takes place on the FreeBSD server. NOT within the jail!
Creating data directories
First, the base directory is created in POOLNAME work with work/bastille_data and mounted in /usr/local/bastille/data/ with
zfs create -o /usr/local/bastille/data data/bastille_data.
The directory /usr/local/bastille/data/JAILNAME/data is then simply created with the command zfs create -p work/bastille_data/JAILNAME/data. The parent directory /usr/local/bastille/data/JAILNAME is also automatically created with the parameter -p.
chmod -R ID:ID /usr/local/bastille/data/JAILNAME/data
Important! Since the target directories often do not yet exist in the jail, they must be created in advance. Some of the directories are only created when the packages are installed, but this is too late. This is because during installation, the content (e.g., configuration files) is copied to the target directory.
This directory can be manually integrated for testing purposes:
mount -t nullfs /usr/local/bastille/data/JAILNAME/conf /usr/local/bastille/jails/JAILNAME/root/mnt/conf
mount -t nullfs /usr/local/bastille/data/JAILNAME/data /usr/local/bastille/jails/JAILNAME/root/mnt/data
mount -t nullfs /usr/local/bastille/data/JAILNAME/db /usr/local/bastille/jails/JAILNAME/root/var/db/pgsql
In order for Bastille to automatically mount the directories, they are entered into the fstab belonging to the jail.
ee /usr/local/bastille/data/JAILNAME/fstab
/usr/local/bastille/data/JAILNAME/conf /usr/local/bastille/jails/JAILNAME/root/mnt/conf nullfs rw 0 0
/usr/local/bastille/data/JAILNAME/data /usr/local/bastille/jails/JAILNAME/root/mnt/data nullfs rw 0 0
/usr/local/bastille/data/JAILNAME/db /usr/local/bastille/jails/JAILNAME/root/var/db/pgsql nullfs rw 0 0
Voilá