I want to deploy a container with Podman on NixOS machine. The container has to mount some directories (bind volumes) - see the code below.
I don’t want to create them manually. Is it possible to define that a certain directory should be present with Nix?
The only thing I found is about systemd.tmpfiles.rules, but on mynixos.com it says that’s for volatile and temporary files. Should I use that for a persistent directory too?
tmpfiles.rules is usually the way to go, it’s used throughout NixOS for exactly this purpose. Have a read through the systemd docs to see which settings to set to make it never clean the directories. search.nixos.org is the official docs search page by the way, no idea what mynixos.com is: systemd.tmpfiles.rules.
A more “correct” alternative is using the systemd option for creating a StateDirectory, if you can figure out how to hook into the underlying systemd service. Shouldn’t be too hard, actually, it’s just something like:
YMMV, however, since it forces those directories to exist in the paths that are typically used for services, and with my config only symlinks them to your home directory. Hence, just using tmpfiles might be better, since this is really about your home directory existing. Personally I feel like this is going to be a permission settings nightmare for you in general, not a fan of mixing user and system services.
Does BindPaths actually create the directory? From the documentation I was under the impression that the unit would just fail if it doesn’t exist yet, with the option of ignoring the lack of directory if you set the correct option.
I’m also surprised you need to set builtins.storeDir in there. I guess without it the unit can’t access certain runtime dependencies? I at least assumed the nix package patched mounting /nix in, very few things should work without it.
Do agree using the NixOS module is typically better, combined with systemd’s sandboxing nix doesn’t really need oci containers.
I remember this happening via some asking around (obviously :D), but have no memory for anything else.
You are right about path needing to exist beforehand, so this won’t be automatically created on a new system (from systemd doc):
Note that the destination directory must exist or systemd must be able to create it. Thus, it is not possible to use those options for mount points nested underneath paths specified in InaccessiblePaths= , or under /home/ and other protected directories if ProtectHome=yes is specified. TemporaryFileSystem= with " :ro " or ProtectHome=tmpfs should be used instead.
Perhaps this is something I need to address. Pointers welcome
Looks like it’s persisted through reboots. Thanks!
I will probably test StateDirectory later
@payas I was thinking about using it, but currently I want to test containers on NixOS (I have some other stuff that’s being run in containers). I may try to go with systemd service later. Thanks for providing your config and your input!
I’ve ran into this, too, and others too I think. I wonder if it would be good to have a nixos module to “create directories” that doesn’t smell like it’s about temporary directories (even if that’s then the implementation), to not throw people off?
No worries, I myself deploy pi-hole via container only. If you figure out how to keep that container updated automatically as new versions get released to docker, I’d be very grateful.
I mean… we could provide another abstraction for users to learn and remember and eventually debug but I think we should ask ourselves what value this provides? Isn’t the right thing to improve documentation and make it very clear what tmpfiles does?
I think naming is still important, and I think a wrapping module isn’t that out of place - there’s networking.useSystemd after all - but yeah that’s a good idea. Updating the documentation to reflect the option’s actual usage is probably more important.