It doesn't handle binary-only applications though (e.g. NoMachine, games, &c.). It has a couple of options to make those work, and it's almost always possible to get it to work natively, so if there's not already a nix expression for the app I want, I just take the expedient path of having a docker container with an ubuntu user-space, since pretty much all proprietary apps run on ubuntu.
It supports Debian/Ubuntu/Arch/VoidLinux currently (Gentoo soon).
With Darch, your entire desktop is scripted and reproducible.
Here are my Arch recipes: https://github.com/pauldotknopf/darch-recipes
I find this to be a better middle-ground between <your favorite OS> and Nix.
That means only commands that are baked into your image are persisted.
That means you can test new packges without fear that it will leave boogers on your machine.
Interestingly, you can use Nix under other distros and even MacOS just fine, due to the way it isolates dependencies: https://nixos.org/nix/
There is a binary cache for macOS now. Hydra build status:
https://hydra.nixos.org/job/nixpkgs/nixpkgs-18.09-darwin/dar...
Edit: apparently packages are distributed in binary by default, but if you customize options it’ll be compiled locally. My mistake.
NixOs is the amalgamation of 3 things: Nix, Nixpkgs, and the other bits it takes to make an os.
Nix is a programming language and a packaging tool. It allows packages to be programmed in a type safe way, then executed to install the actual libraries or binaries. This is the area of the system that I actually know the least about.
Nixpkgs is a large collection of packages for Nix. The community really has worked on this set of stuff like gangbusters, it's quite impressive how many things they've wired in from scratch. Each package specifies its dependencies, and the various options it accepts to tweak various options. A good example would be setting the data directory for the postgresql service.
NixOs combines the previous two items along with the other bits it takes to make an OS work. So they provide official installation instructions and media, configure how Nix is going to actually be run on NixOs (as compared to say, OSX), provide stable channels for various versions, etc. Basically all the regular things you expect out of a distro.
Personally, I'm not exactly sure if this is where Linux is going to go, but I think that this is how Linux would have been built if disk was much cheaper back in 1970ish. A lot of the regular problems of systems management are completely solved in NixOs.
Need two different versions of the same shared library? No worries, they can each have their own copy, and Nix will automatically make sure the correct one, specified by the hash of all the build flags, will be the one that's loaded into memory for said program.
Have a shared system? Great! Users can install userland programs without root privileges. Because items are inserted into the nix store idempotently and paths are not universal, I can install vim without any other users seeing that, and without root. The only thing that takes root privileges are services (e.g. Postgres), or installing programs for universal access.
Sadly this does come with some downsides. A lot of programs over the years have come to make very bad assumptions about program location, or the ability to modify the PATH variable. A good example of this issue is RVM, which for the life of me I could not get to work.
Like, if you add a little patch to libpng as an overlay over your entire system, then you'll recompile a lot of stuff, but you can also choose to only use that custom libpng with a specific package.
Even in the latter case, it's true that Nix will always recompile the package that depends on libpng, instead of using dynamic linking and only recompiling libpng. This is because Nix has no way of knowing how your libpng patch will affect its reverse dependency, and because link paths are always content-addressed in Nix for reproducibility.
https://nixos.org/nixos/nix-pills/override-design-pattern.ht...
https://nixos.org/nixos/nix-pills/nixpkgs-overriding-package...
Those are the documentation pages I found right now...
It's basically two steps: constructing the patched libpng derivation, and then overriding the libpng derivation in the specific program.
The first step would be something like
let myLibpng = pkgs.libpng.overrideAttrs
(old: { patches = old.patches ++ [~/libpng.patch]; });
and the second step would be something like let myProgram = pkgs.program.override { libpng = myLibpng; };
and then you could include "myProgram" in your system package list.If you have an "overlay" set up in your system then you could also do this as part of that overlay.