4 ms·
> I don't understand how these are comparable They fulfill similar business functions - allowing you to run the same code on a bunch of dev machines and on pro
by lolpython 5y ago
> I don't understand how these are comparable
They fulfill similar business functions - allowing you to run the same code on a bunch of dev machines and on prod (modulo modifications for e.g. database storage in Docker's case). Nix people get hung up on the fact that Docker runs containers, but it doesn't really matter that much. Often Docker is the shortest path to getting software running on multiple machines reproducibly.
> I also don't understand what you mean by "bindings"
I am referring to derivations and modules. Both are glue that you have to write for existing software that is already packaged. With Docker you leverage the existing packaging ecosystem like pip or apt. The packages are already written for you, and you can follow the installation instructions from a project repository and they translate seamlessly into Docker.
For example with ML & Python - If you want PyTorch with CUDA support, you can follow the official documentation [0] and basically copy and paste the installation instructions to a Dockerfile RUN statements. If anything breaks you can file an issue on the PyTorch issue tracker which has a wide audience. With Nix you have to write glue on top of the installation yourself, or a maintainer does it with a much smaller code review and support audience. Sometimes the audience is just the author, given that Nix project people commit directly to master frequently and do self-merges of PRs [1]. And there are other hurdles like compiling Python C extensions, which are pervasive.
Another example is with software systems, I guess this would be a Nix module. Here's GitLab: [2] where it was really difficult to translate the services into Nix. But a lot of company internal services can look like GitLab with a mix-mash of odd dependencies and languages. And writing a Dockerfile for this is much easier than Nix, since you can copy from the existing README specifying the Debian or language-specific dependencies. (edit: and if there are conflicts between dependencies of the services they can go into different containers. Getting the benefit of Nix - reproducibility - without the extra effort.)
[0]: https://pytorch.org/get-started/locally/ https://pytorch.org/get-started/locally/
[1]: https://discourse.nixos.org/t/proposal-require-pr-authors-to-review-other-prs/16242 https://discourse.nixos.org/t/proposal-require-pr-authors-to...
[2]: https://news.ycombinator.com/item?id=14717852 https://news.ycombinator.com/item?id=14717852
- chriswarbo 5y ago> With Docker you leverage the existing packaging ecosystem like pip or apt. with import <nixpkgs> {}; runCommand "my-python-package" { buildInputs = [ pythonPackages.pip ]; } '' cd ${/my/project/dir} pip install ''
- iterati 5y agoThat compared to `RUN pip install <package>` is probably one of the things people are complaining about, no?
- chriswarbo 5y agoI think the complaint is about things like: (import <nixpkgs> {}).pythonPackages.callPackage ({ buildPythonPackage, dep1, dep2, dep3, pip }: buildPythonPackage { pname = "my-package"; version = "123"; propagatedBuildInputs = [ dep1 dep2 dep3 ]; doCheck = true; src = /my/package/dir; }) {} That's how Nixpkgs tends to do things, which has nice features like building each dependency separately, allowing easy overrides, etc. but it requires knowledge of how Nixpkgs orchestrates its Python packages. In contrast, 'runCommand' lets us just run a shell script like 'pip install', which is easier but doesn't have those niceties. Also, depending on the platform, the Nix sandbox may have to be disabled for 'pip install' to work, since Nix tries to prevent network access (I think it's enabled by default on Linux, but not on macOS)
- soraminazuki 5y ago> and if there are conflicts between dependencies of the services they can go into different containers. Getting the benefit of Nix - reproducibility - without the extra effort To be clear, are you suggesting that RUN sudo apt-get update && sudo apt-get -y install ... is somehow reproducible? I'm asking because I was surprised to see the above as being described as "reproducible" of all things. Splitting that into many different containers would likely exacerbate the reproducibility problem instead of improving it. > With Docker you leverage the existing packaging ecosystem like pip or apt. The packages are already written for you This is even more true for Nix, which has the largest and most up-to-date package repositories out there[1]. Plus, with Nix, you can easily make a new package based on existing packages with a mere few lines of code if the existing packages doesn't fit your needs. Other package managers besides Guix doesn't offer you that flexibility so you'd have to compile from scratch. That's way more tedious, hard to maintain, and definitely not reproducible. [1]: https://repology.org/repositories/graphs https://repology.org/repositories/graphs
- lolpython 5y agoI am frustrated that you ignored my main argument about Docker sufficiently serving the same business function as Nix, with lower maintenance. Instead you focused on a semantic argument about one word in my post - "reproducible". You have the wrong idea about reproducibility, where you say basically everything that is not Nix or Guix is not reproducible. This ignores things like conda and techniques like package version pinning that allow researchers and businesspeople to get the same results from the same code. Here's a definition of "reproducible" from Wikipedia: Any results should be documented by making all data and code available in such a way that the computations can be executed again with identical results. https://en.wikipedia.org/wiki/Reproducibility https://en.wikipedia.org/wiki/Reproducibility ----- > To be clear, are you suggesting that > RUN sudo apt-get update && sudo apt-get -y install ... No, you need to pin the dependency versions. With Python this practice is already normalized with requirements.txt or conda yml files. So you would take an existing project and do: RUN conda env create -f environment.yml which would likely be copy-pasted from the project README. The yml file specifies version numbers for dependencies. The SAT solver is deterministic. For other languages like C maybe the project didn't specify dependency version. So you need to figure them out when you first get a successful build, then specify their versions in apt. You can specify version numbers in the apt-get install line. Yes, this is reproducible. Definitely good enough for most business use cases. When I say reproducible I do not mean ivory tower math proof reproducible. I just mean that the code will run on the relevant machines they are targeting. As I wrote in my initial comment. And as I defined at the top of this comment. Also Nix provides a worse experience for pinning dependency versions since it does not have a native concept of version numbers [0]. Instead people have to grep through the Nixpkgs repo to find the correct hash of their dependency version. > This is even more true for Nix, which has the largest and most up-to-date package repositories out there No, Docker has the closure (to borrow Nix's terminology) of all of the package managers in that graph. If you add the height of the Debian packages with Pypi and Hackage you already have Nix beat. You can keep adding - cargo, ruby gems, etc all in their native package managers. If Nix were better off then people would be adapting Nix packages to other ecosystems. But the reality is the other way around. > Plus, with Nix, you can easily make a new package based on existing packages with a mere few lines of code if the existing packages doesn't fit your needs. Other package managers besides Guix doesn't offer you that flexibility so you'd have to compile from scratch With Nix, you are forced to make new packages based on existing packages. That is not a benefit. Regarding "if the existing packages doesn't fit your needs", compiling from source is not a big deal since Docker caches output artifacts. [0]: https://github.com/NixOS/nixpkgs/issues/93327 https://github.com/NixOS/nixpkgs/issues/93327