Hi, I am looking for resources that explain why would someone turn to Nix, and not just use Docker for the purpose of reproducible builds. In other words, can the same reproducibility “guarantees” that Nix provides be achieved with Docker alone?
I don’t know of any such resource, but I can give it a shot. I guess there’s a bunch of facets to this depending on your use case. You might want to have ‘reproducible builds’ just to make it easy for your users to build your software without hassle. You might also want ‘reproducible builds’ in the https://reproducible-builds.org/ sense: to make the build progress auditable for security reasons and produce a verifiably-consistent result.
For the “I just want to make it easy to build my project” use case, providing a binary docker image in which to perform the build might be fine.
If you also want it to be auditable, Nix provides a couple of advantages. If you want it to be auditable, you wouldn’t distribute a binary docker image (as it’s hard to audit whether there are hidden evil things in there), but instead a Dockerfile
that allows the auditor to build his own docker image. In most traditional distro’s, such a Dockerfile
would start with installing your dependencies from the distributions’ binary repo’s. If you are using a non-rolling distro, that is likely fine, but for some dependencies recent versions will not be available. If you are using a rolling distro, you can expect to find more recent versions of your dependencies, but your build has become less reproducible: if you generate the image again, it will download the ‘latest’ version of the dependencies, which might have updated to an incompatible newer version. With nix, all the package definitions you’ll likely need are in a ‘monorepo’, https://github.com/nixos/nixpkgs. This means you always have the advantage of being able to select an up-to-date version of the tree, but at the same time each version has a unique git hash that you can point to to get that exact set of dependency versions again.
While the nixpkgs tree has all the information you need to build all those packages, typically pre-built results will be available on https://cache.nixos.org so Nix will just download those, similar to how a traditional binary package repo works. However, if https://cache.nixos.org ever goes away (or if you are really paranoid), you can choose not to use it and build everything yourself. This does of course require all the sources are still available, which gets less likely over time.
I think this sums up the main differences I see, are there any other aspects you are interested in?
I think you should have a look at this talk from Graham Christensen for an indepth
explanation:
Graham will be talking about how Nix and Docker differently model the relationships between software.
Nix is a package manager and build tool. Its design automatically provides for reproducible builds and dev-prod parity. Nix’s dependency model automatically and efficiently generates OCI-compatible containers with only the required run-time dependencies. Without alpine, or FROM scratch, while also reducing rebuild and test time.
These containers seamlessly integrate with existing container-based deployment workflows, while bringing the reproducibility and traceability benefits of Nix.
There is work by Tweag to upload all sources to the Software Heritage archive. So, this should become less of a concern in the future:
Yes, thanks for clarifying the differences. I am interested in reproducible builds for auditing purposes. That is useful information, thank you.
Thanks! I’ll have a look!
These may also be helpful: