Is a Nix-based FHS-compliant distribution possible?

Note: I am new to GNU/Linux and Nix, and know nothing about their implementation details. Feel free to pick out my faults.

Nixpkgs can already build FHS environments and drop the user into them. While limited in configurability, this has allowed some stubborn packages (such as vscode-fhs that manages extensions itself) to be built with Nix. Now can this be augmented to the whole OS? I mean, instead of creating tons of symbolic links (especially for Home Manager) and wrappers, copy all necessary files into a FHS compliant sandbox, and let the user log in from it. This may

  • increase the compatibility with pre-built binaries;

  • make temporary mutations, such as modifying Nix-controlled files, that were rollbacked automatically after reboot, at least easier;

  • make a smoother learning curve possible: with a delicate front-end for system configuration, the user could do things just as in “normal” distributions, yet enjoy all the advantages of declarative configuration if they want;

  • strengthen security? I know little about the containerization technologies of Linux; just guess that if /nix is invisible to the user and their programs, and files are copied rather than linked, the core components of the OS would be more secure?

  • and hide the details. This is a personal preference. Each time la get invoked, the symlink target paths with a 32-char hash appears just annoying to me. They’re like saying “No, this file is legally governed by Nix only. Ask for permission from it or you’ll have to destroy the precious declarative immutable system.” If where the declarations get realized by Nix differs from where they work, then the problem would be solved.

Copying a whole OS may take numerous disk spaces, but /nix/store already takes so much, so I guess this would not be a big problem…

You could do that it’d be quite simple. buildEnv with a bunch of paths and copy at activation. It’s even been attempted to be upstream into NixOS before.

The problem with this approach is that you’d undermine the very principles that make Nix Nix which is to say that there are no global shared paths and being explicit about dependencies.

As soon as dependencies are available through some global shared path, it’s possible to miss declaring them. This is already happening with executable dependencies (executables in the global PATH) to some degree but thankfully they’re rare.

If you really want to run unpatched binaries, use nix-ld.


Are you sure you want anything from Nix anyway? Mere snapshot-based atomic upgrades are available elsewhere, and if you want a system working according to FHS being designed for FHS is a plus.

That’s true. But in my opinion, “never conflicting” is hardly “the very principles that make Nix Nix”, not only because what you have mentioned (the conflicts of shared PATH, etc, still hold the possibility), but also because that there are plenty of other ways than NixOS, including nix shell and containers, aimed to achieve this. Instead, giving up the global “pluralism” for a “simple and stupid” login rootfs, while still enjoying the declarative design, could be convenient for a not-so-small amount of users.

I enjoy everything from Nix, except for those symlinks outside XDG_DATA_HOME. So called “atomic” or “immutable” distributions are interesting, but they can’t be declared and defined like NixOS, let alone their built-in inconsistency (e.g. flatpak and toolbox bound with Fedora Siverblue) and inconvenience (a dir in / is either simply mutable or absolutely immutable).

FHSenv would seem better for almost everyone capable of implementing a Nixpkgs-based boot sequence, so this argument is not going to convince anyone to do anything.

I think buildEnvs that include symlinks outside the store are not that rare (and some NixOS modules probably rely on such tricks). Which lets you make a system allowing specific overrides (not so easy for libraries, though, true, there you need hacks like replaceDependency too). Except see later — what you propose will be even more confusing because /nix/ won’t go anywhere.

We are already not so good with clean abstractions, so to get any real advantages you need to learn quite a lot, and adding another leaky abstraction will only serve to lure people who will have problems later while actively obstructing them from figuring out the solutions.

Erm, /nix/ will not be invisible because /nix/store/ paths are hardcoded in a lot of places and this is a core part of how Nix/Nixpkgs handle installation of incompatible versions. So now some things will go through copies and now through /nix/store/.

You will still need those details to get things working…

Isn’t there anything that just debootstraps a fresh system from a list of packages and switches? And any convergent-configuration system should work pretty well when starting from a cleanly debootstrapped image.

If declarative configuration is of any value, you will need to troubleshoot it (presumably you don’t just want a stock install of whatever). And if you want to think in FHS and hide the details contrary to FHS, the ecosystem embodying «FHS has grown out of old mistakes» as a design principle will only provide you with the most frustrating tools and instructions for troubleshooting.

1 Like

I’m not going to convince anyone to do anything, but just another one asking for technique information about whether an alternative to status quo is possible or why it is not. If this is indeed the best trade-off, then I’ve been content. Thanks.

You might (maybe accidentally) convince someone to improve something specific about FHSenv! Not sure what exactly, but you do have an articulated enough set of preferences to describe some drawback that I (and probably some others) have just learned not to notice, when rarely using FHSenv.

Some of your assumptions about Nixpkgs are too optimistic though. Sometimes for reasons that we would like to see resolved (copying and changing store references to direct references would probably use the same tooling as copying to a store with a different base path, which would be nice for some non-root use cases on shared servers) but find too complicated to do well (e.g. there are store path references within compressed objects like .jar and manpages), even…