Nixos is a great distro with a great idea behind it, even though it’s packages are immutable it doesn’t mean it can’t benifit from being truly or mostly immutable (except where maybe data is changed). Or have the option to be immutable. There are a few use cases that are practice and some less so, like. I accidentally rm -rfed my system trying to delete what I was unaware of is a symlink, however this itself isnt reason enough and there are plenty of other benifits from a truly immutable nixos.
The closer you get to full data immutability, the more corner cases arise, but I agree that it is nicer to have /etc
point to an immutable path in store that symlinks mutable data where appropriate, than to have a mutable switch-time populated /etc
with links to immutable things. I have given up on NixOS mainline for other reasons, so in my nix-generated system setup I do have this mutability inversion and like it.
The system really lives in /nix/store
which is normally mounted read-only, I believe. (but I guess that’s tangential to the real topic)
What would you make immutable? Ok, let’s go though the root:
special filesystems:
- proc
- dev
- sys
shouldn’t be read-only:
- tmp
- var
- run
- home
trivial to make read-only:
- bin
- lib
- lib64
- usr
already read-only:
- nix
could be read-only:
- etc
- root
/root
is the home of the root user, it could be made read-only, but I don’t think there’s much to gain from this and it would make rescuing a system slightly annoying.
/etc
is really the only directory that would benefit from being read only. We already have /etc/static
which is a symlink to /nix/store
and contains all generated files. Every other file is either a link to /etc/static
or was written imperatively, so you’d think you could make the whole /etc/
a symlink, however there are some caveats:
-
passwords, users, groups are generated at activation time. These are intentionally not stored in /nix/store but should still be present under
/etc
. -
resolv.conf
needs to be writable at runtime by programs usingresolvconf
. -
more generated files used by programs like CUPS or LVM.
So, the only way to make /etc
read-only would be to use an overlay filesystem that combines the /etc
generated by NixOS and some writable path under /var
or /tmp
. I think it shouldn’t be too difficult to achieve, but it doesn’t look like much of an improvement over the status quo.
Instead of trying to make the whole root read-only, I think the better approach is to make it impermanent. This means every change you don’t care about will be lost when restarting the system.
There is the convenience vs correctness tradeoff at play from what i understand of this. For example being able to quickly connect to a wifi network without rebuilding the system is important when you want to do something quickly. (Which is why my systems live on a tmpfs
except for /nix
and /home
to remove such state after reboot) NixOS gets a good middle ground in that IMHO (for desktop usage), but servers would likely benefit from total immutability to prevent unaccounted tempering/experimentation.
This is not correct, my system has /etc/cups
symlink to mutable stuff in /var/
and read-only /etc/
proper instead of /etc/static
as the read-only part and multi-step /etc/
symlink update logic
Right, that works too. In any case, you have to handle every program that could write to /etc
.