Raito's opinionated FAQ on Nix/NixOS/whatever

(Dernière version: feb 2024)

What is this?

This is an opinionated FAQ, made by me, with personal hot takes. It encompass my knowledge and my vision of how to use Nix/NixOS.

It is by no mean meant to make Nix/NixOS easier to use, it is made to answer various systematic questions people tend to have in this ecosystem once and for all.

Q: Should I use flakes or not?

Short answer: No.

Long answer: No:

are two excellent blog posts to explain you why not do that.

Whenever I see flakes in a project and I do not understand the reason for why this is in there, what does it tell me is that you may not understand how Nix works. This is fine, but you may want to revisit this in the future.

Alternatives to dependency management tooling consists of:

Or the one you write.

Alternatives to pure evaluation and various Flakes features can be found in the stabilization RFC of Flakes.

Q: How to do incremental builds with Nix?

Q: I am rebuilding the world after upgrading or adding this package, why is it the case??

Nix rebuilds exactly what you need. So if you are rebuilding the world, you need to do it.

Assuming this, you can easily derive why this happens.

  • First hypothesis: you are mixing up NIX_PATH, when something does not rebuild in your shell, but rebuilds in your configuration, this means, they consume from two different nixpkgs. One has cached packages, the other does not.
  • Second hypothesis: you are offline or cannot reach https://cache.nixos.org.
  • Third hypothesis: you are overriding/swapping/changing a low-level dependency and you don’t realize this will cause you to rebuild your system all the time, e.g. openssl, systemd, glibc, etc.
  • Fourth hypothesis: you have store corruption and your source tree containing Nixpkgs is corrupted.
  • Fifth hypothesis: you are hitting a Nix bug and you want to carefully review a nix-diff of the two derivations.
  • Sixth hypothesis: https://cache.nixos.org has a problem

From there, you can work out what is going wrong.

To avoid NIX_PATH discrepancies, you can use that snippet to force a synchronization:

  nix.nixPath = [
    "nixpkgs=${nixpkgsUnstableSource}"
  ];

Combine this with a shell that can reload in realtime the initialized variables so that it can propagate in every shell every time you upgrade it. Otherwise, you will need to create new shells / login sessions for the new input to take effect.

Q: Should I use initrd secrets?

Short answer : Absolutely never.

Long answer : No, really.

If you are an expert, you know better, you should tie a proper system to identify the machine pre-boot. If you are not an expert, you are setting yourself for failure.

Initrd secrets are supposed to be secrets. In practice, most of the time they are glued to your initrd.

Your initrd is in your boot partition. Your boot partition can be read by physical attackers because it’s not encrypted.1

Your boot partition can also sometimes be read by virtual attackers, because, well… it’s a boot partition, why should it be protected?2

Therefore, your initrd secrets are not so-secrets.

So why are they called like this? They are called like this because they protect those files to end up in the Nix store, everything that the Nix store sees gets copied over there and Nix store is world readable, so it’s even less protected than your boot partition from a read perspective.

Now, think about your threat model. Do you really need to defend that SSH private host key against a serious attacker with initrd secrets? If so, I hope you remark that putting in your boot partition is roleplaying as a security person.

Consider using a proper scheme: https://github.com/latchset/tang or a TPM2.


  1. No, GRUB encryption does not solve that problem, think about it.↩︎

  2. It’s protected those days, but you have no guarantee and the protection is thin.↩︎