Docker is not reproducible, you just apt-get install what you want hoping that the RUN commands get you a version that is still compatible with your software and doesn't break anything. With NixOS, you can pin the specific hash of every software, and you don't need the entire Ubuntu 20.04 in a container to deploy a webapp.
How does apt-get install handle the following scenario?
You need the following software:
- You need the latest release of Erlang for your app
- A database (like Riak), whicn in turn happens to need an older version of Erlang
- The new Erlang needs the latest libopenssl
- The old Erlang needs an old v1.x libopenssl
- You used some open source software written in C++, so you need libstdc++
- Some of your own C++ code has exposed a bug in libstdc++, so you need yet another libstdc++ with your patches, but just for that software
- Etc
How does apt-get install allow you to have multiple versions of a given dynamic library (with the same SONAME) and multiple binaries (erl, clang, etc) installed at the same time?
The answer: it doesn't.
Nix has no problem handling everything I described above, and it handles it easily.
So, yes, you can pin versions with apt-get install, but you're out of luck if any of those packages have any transitive dependencies with different versions.
Also, the pinning guarantees are higher with nix: you can be guaranteed that your packages and their transitive dependencies are byte-for-byte identical, every time. Pinning end-to-end across all packages (and every transitive dependency thereof) is not a normal, happy-path thing to do in apt, so you would be hard pressed to find anyone that does that, given how onerous that would be -- whereas it's trivial in Nix.
What's the model of the pinning? Is it an arbitrary semver? Is it a sha256 calculated by the content of the package (Content Addressed)? Is it a checksum calculated from all the inputs that were used to create the package install spec (Input Addressed)?
At best, you can do something like this: apt-get install gparted=0.16.1-1
That handles the semver case, but that doesn't address the rest of the "all of the above":
- sha256 calculated by the content of the package (Content Addressed)
- checksum calculated from all the inputs that were used to create the package install spec (Input Addressed)
> Nix isn’t the first package manager to do something unique.
Sure. But it is the first package manager to do the above unique things. After all, the reason for Nix's existence is just that: no other package manager before it has done what it does.