The NixOS configuration has environment.etc. Home Manager has home.files. I’m currently using both to symlink files into place from a persistent location.
As far as I can tell, this is also what Impermanence does. So why do people use it? Does it do a better job? Does it handle directory locations that the default configs can’t?
I assume I don’t need it, but I’m probably missing something.
The idea of impermanence is that upon reboot, the machine loses its state and in the case of NixOS gets recreated from your configuration (stored in a persistent area of your file system). So any erroneous state changes (accidental or otherwise) are lost between reboots.
The persistent area will hold some important data - perhaps ssh keys (depending on type) and passwords that you may need beyond your configuration.nix (or flake)
It does not affect your home folders.
I found Guekka’s blog are good resource - NixOS as a server, part 1: Impermanence | Guekka's blog
I use it - as much to find out more about it as anything else.
If it interests you, try on a spare machine first.
Please do not post LLM-generated content without verifying that it is correct. This reply is four paragraphs of mostly saying the same vague thing with a few confusingly wrong pieces of information it hallucinated sprinkled in.
It also doesn’t do exactly the same thing, rather than symlinking read-only, nix-prepared files into place, it creates read-write bind-mounts of files that nix never touches.
I.e., with environment.etc and home.files you can instruct nix to put pre-written files created at build-time into places that will exist at runtime, but can never be modified. environment.persistence will just make paths available at certain places for reading/writing, but they will be empty by default and are intended to be written at runtime.
Is false, by the way, the impermanence module actually has provisions for doing this in your home directory as well. What gets cleared is entirely up to the user.
rather than symlinking read-only, nix-prepared files into place, it creates read-write bind-mounts of files that nix never touches
Ah! Okay, this is a bigger difference than I thought. Read/write, and would solve the issue where some programs don’t like their directories to be symlinks.
Another question comes to mind. Does Impermanence require that root get wiped at every boot? Or can it be used like environment.etc in that it sets up the link if it doesn’t yet exist?
I’m wondering if I can use Impermanence now to get things organized, and decide to start wiping root at a later time.
I’ve already planned for eventually wiping root, I’m using btrfs and have a blank snapshot. I’m just hesitant to pull the plug until I know everything else is working.
Yep, totally possible. In fact, since tmpfs requires lots of ram people don’t always have, I think it’s pretty common practice to just use a normal partition to hold the data, and then clear it with initrd.postDeviceCommands.
@grahamc - who I believe started this practice with this blogpost - apparently uses an empty zfs snapshot they restore at boot time, for example.
If you just want to test things out you can just not delete your data on boot.
I was pondering today if it might be helpful to my journey of adopting impermanence to first snapshot the existing / root folder and than reverting to the blank snapshot.
That way I should get the benefits of a clean root filesystem without the issues of actually loosing data.
I can’t find the post anymore, but someone found that using postDeviceCommands is anyway too early for at least btrfs, and can cause data loss. It will also stop working if the systemd init ever becomes the only option.
Reading through @kjhoerr config, I found an additional service hardlinking /persist/etc/machine-id in a separate systemd service, instead of environment.persistence."/persist".files
If you include /etc/machine-id in environment.persistence."/persist".files, then the systemd initrd will generate a new /etc/machine-id on every boot. From the Freedesktop documentation,
Otherwise, if /etc/machine-id does not exist, this is a first boot. During early boot, systemd will write “uninitialized\n” to this file and overmount a temporary file which contains the actual machine ID. Later (after first-boot-complete.target has been reached), the real machine ID will be written to disk.
You have to hardlink the file early or else systemd will think it doesn’t exist and then generate a new one.