I am looking for the recommended Fedora CoreOS pattern for separating container storage/application data from the OS disk.
My goal is:
Keep the FCOS root disk small
Put container images, writable layers, volumes, and other growing application data on a separate virtual disk
Encrypt both disks with LUKS + Clevis/Tang
Have the secondary data disk be independently expandable and growable live
My first approach was to mount the second LUKS volume directly on: /var/lib because this is where container runtimes normally store their data.
This mostly works during normal operation, but I noticed issues on the first reboot immediately following an rpm-ostree update. The new deployment boot does not always complete correctly (including LUKS auto-unlock behavior for the secondary disk). A subsequent reboot usually works.
This made me suspect that replacing /var/lib introduces ordering/dependency issues during the first boot into a new OSTree deployment.
Is mounting a separate filesystem over /var/lib considered unsupported or discouraged on FCOS?
Specifically:
What is the recommended location for a separate application data disk?
What is the recommended way to relocate container storage on FCOS?
For an encrypted secondary disk unlocked with Clevis/Tang, what is the recommended systemd ordering pattern?
Are there existing examples or recommended Ignition/Butane snippets for this layout?
I would like to follow the intended FCOS design rather than fighting the immutable OS model.
Note there is currently a bug in systemd that affects mounting over /var (and i assume also /var/lib) from a luks encrypted volume. We are waiting on a fix to be made.
After quite a bit of troubleshooting trying to mount a secondary network-encrypted (Clevis/Tang) volume directly onto /var or /var/lib, I repeatedly hit unresolvable systemd ordering cycles during boot (tracked via journalctl -b 0 | grep -i "cycle").
The Root Cause
Mounting a network-encrypted drive anywhere under /var creates a conflict with systemd’s default lifecycle assumptions. By design, systemd treats /var subdirectories as local OS targets (local-fs.target), meaning it tries to mount them before initializing network services.
However, because a Tang-backed volume explicitly relies on NetworkManager and gssproxy to fetch decryption keys, systemd hits an unresolvable circular dependency loop: it cannot start the network stack until the local filesystems are mounted, but it cannot mount the filesystem until the network stack provides the key.
The Solution
Instead of battling systemd’s local OS tracking constraints, the cleanest approach is to move the mount location out of the early boot tracks entirely (e.g., to /var/mnt/data), configure it as a remote device using _netdev, and tell Docker and Containerd to look at the new path instead.
To achieve this cleanly, you must also drop Butane’s automatic mount unit generation (with_mount_unit: false) so that Butane doesn’t force it back into local-fs.target.
Here is the finalized working Butane configuration for anyone else fighting storage dependency loops: