Ask HN: Does NixOS live up to its promise?
NixOS.org summaries itself as “Reproducible, Declarative, Reliable”.
But you cannot specify the exact package version # in you build config file to use (lack of being declarative).
As such, packages get updated making your build environment change over time, which seems to be inconsistent with the principle of being reproducible and reliabile (since version changes might break your environment).
The principles of Nixos sounds wonderful and would solve real world problems. But does NixOS deliver on that without being able to specify exactly package version #s?
Note: see this Github ticket from 6+ years ago (2015).
https://github.com/NixOS/nixpkgs/issues/9682
4 comments
[ 0.25 ms ] story [ 13.6 ms ] threadYou have three options afaik:
1. Pin your package repository
2. As answered in your last linked issue: specify a package with git
3. Build it yourself
I think this compromise is gold. Update your package registry and get the latest stuff (or even bleeding edge if you point to unstable), pin manually when you care about the version.
Are you saying that I could do the follow (pseudo-code) in my configuration.nix file just by pinning?
-------
nixOS = 21.11 # use this as the base
add_packages = [ "postgres" = 14.1, "redis" = 6.2.6, "nginx" = 1.21.6 ]
-------
Also, where does Flakes fit into this picture?
See https://nixos.wiki/wiki/Flakes#Input_schema for some idea on how it would look.
The main obstacle for you here is learning the Nix language and how to use it for nix packages. It's not an easy task, but it does meet your requirements.
https://nix.dev/ is a good resource in addition to https://nixos.org/manual/nixos/stable/ and https://nixos.org/guides/nix-pills/
Yes. An example that i had to do recently. I forget the exact issue, but I wanted to express the thought: "keep the rest of my system up to date, but pin only the notmuch package to an older version. Oh, and to make sure it is not unspecified: that older version should also use the dynamic libraries that it is tested to work with, potentially older than the rest of my system."
in code; ``` nixpkgs.overlays = [(self: super: { notmuch = nixpkgs-old.legacyPackages.x86_64-linux.notmuch; })]; ``` Where nixpkgs is basically 21.11 and nixpkgs-old is a particular git commit hash.
But you can express other nuanced thoughts as well: - bring in an old application, but don't change anything else on my system (non-interference) - patch some core library, AND recompile EVERYTHING that uses it (global replacement) - only replace a core library for the software used for a particular service, no where else (targeted patching) - change some ./configure flags but otherwise track the latest security updates for a release, recompile only the things needed (dynamic customization) - recompile everything with optimization flags (source based distro) - only update what github revision used as source for an application, otherwise everything the same (stay on bleeding edge for a specific application)
I think people tend to overthink Flakes, they are a standard code organization schema and an entrypoint into the Nix language that ensures everything is tracked and locked. It makes things reproducible, both the successes and (perhaps more important!) the bugs and failures.