I can see how it would be a good system for ruby or python packages, or a docker replacement.
But it seems it isn't able to blindly mirror stuff from pip, for example? Or to just package any linux under the sun, like Docker can? You'd have to have a nix-specific version of every package you want to use.
And then, the first time you hit upon a package it doesn't have, you have to develop and maintain your own version of it (as far as I understand?). This sounds like a lot of work for someone who wants packages to just work, so they can focus on other things.
I remember using freebsd at some point. The annoyance of not being able to just grab a deb from random sites and install them far outweighted any benefits I got from a cleaner OS organization and some extra features. Nix feels the same way.
I am not saying nix is a bad idea or that it'd have no benefit. Just that, for non-enthusiasts and non-early adopters like myself, it's dead in the water until there is some major support behind it.
I use NixOS on a server and it is wonderful there where my needs are basic and on the well worn path.
But there's no chance I would want it on my development machine. Even something as simple as installing a python package that isn't in the main repo doesn't have a straightforward solution. There are half a dozen different approaches people take, almost none of them well documented. And most of them involve writing 50 lines of esoteric nix, your own derivation, or a complicated flake (which everyone says to use, but there isn't good documentation). Maybe it is great for those on the inside, but from the outside it looks like a disaster. And that's the last thing I want to deal with when I need a package installed to get my work done.
I've thought the same for a while, and now I'm looking to Nix[1] as a solution. Upside: strong fundamental design, extreme reproducibility, great Haskell support. Downside: small community, middling OS X support, essentially non-existent Windows support.
It's still squarely in early adopter territory and the documentation is woeful, but if you're willing to put up with that it really does feel like the "one true package manager" I've been searching for. I've been using it at work and while the setup was painful and some things are still awkward (ie statically linking Haskell executables), it's been incredible overall. The up-front work in learning the system and getting it running has paid off already, and it'll pay off even more as I continue using Nix for other things.
That sounds reasonable, but it kinda makes me question NixOS' value proposition. It seems that any one of the current distributions works well as a generic base for containers.
There are probably lots of systems running standard Linux packages with more complex configurations (i.e. Mailservers, maybe databases, proxies etc) where I could imagine it being useful? Or maybe their desktop work makes more sense than I thought–my desktop environment is much more customised than any server, and I've never tried if the setup scripts I try to maintain actually work.
That's a fair point, I don't have the same expectation of other os-level package managers.
There are alternatives in other projects that bridge build system and package management while directly addressing versioning of dependencies e.g. Spack, Conda, ... The first in particular does exactly what I want, so I suppose I should just be happy with it. Still would be nice for Nix to compete in the same space, esp. with the really slick translation from local to containerized environment displayed in here
I strongly disagree. Creating a Nix package is significantly easier than creating, e.g.: an Arch package, from my experience. packageOverrides is really nice too.
I played around with Nix (not NixOS) a bit. First I tried to use it for managing python dependencies, but that didn't work out properly because some of the python modules i needed were only available on APT.
Then i tried to use it for managing different compiler versions. It was super easy to install GCC in many versions, but then come compiler time I couldn't compile anything because some libraries (that are not in my power to change) used hard coded absolute paths to standard library dependencies, that would in turn include incompatible files from the compiler.
So in essence I would have liked a replacement for Docker, but the issue is I couldn't get the Nix way of doing things to interoperate with the non PyPi Python World, or existing libraries.
This isn't quite the fault of Nix, just that I couldn't use it in a bit more complex real world scenarios.
This is true, I can put nix apps in a container. It improves the reproducibility of builds, but it still wastes disk space, because the container is still based on layers and not packages.
> There is definitely a bit of a learning curve but the time investment is frequently over exaggerated
I'm not talking about the learning curve and its time investment, I'm talking about design problems. Nix's invasiveness is completely unnecessary in modern Linux, it makes its installation a very special case and requires lots of patches to just get stuff to work in nix. The fact that nix patches built binaries so that they point to correct shared libraries locations is a crutch which shouldn't be there in the first place.
It also tries to reimplement pretty much every package manager and build tool, even if they already work well and provide the reproducibility guarantees, including cargo, poetry, npm/yarn. This is a time investment, but it doesn't help me build software that is more robust and correct, that part is already handled for me. Instead, it just worsens the DX, as it forces me to use tools non-native to the ecosystem without first-class support for commonly used features.
A lot of odd Nix hate in here, or at least extreme dislike.
NixOS is so very usable. There are a lot of foot-guns but that's true of Linux systems.
It takes some time to get comfortable with all the different ways to configure stuff. There's a new language, a new build system, a new Linux distribution.
I've spent very little time relative to say, figuring out dpkg or systemd, or learning Bash or C or Perl, or learning the Linux FHS.
NixOS makes running deterministic systems driven from a single configuration incredibly easy.
Nix the language and tools allow you to build software deterministically and create environments where that software is available (e.g. on $PATH).
Nix Flakes is an experimental feature aimed at bringing reproducible and hermetic configurations of dependencies into the fold (i.e. lock files, ala Gem or Cargo or Go Modules).
Nix-the-tool's interactive "package manager" should be deprecated, as it's a huge pitfall for most developers. But it works and is frankly a good first step for folks coming from Apt or Homebrew.
Learning to write modules is probably the steepest learning curve, but compared to learning how to build RPMs or Dpkg or Brew recipes, it's really not bad at all. I actually find it easier and I've been at this for less than a year. Sure, if you're trying to get something working no one has figured out yet you may be in for a pickle, but that feels like it's always been true. The difference is a lot of software breaks and bends the rules and boundaries constructed to keep things and people sane. Nix does not allow that, generally, which is a very good thing. Fixing other people's garbage is the bane of any package system maintainer, it's no different here.
I spent a lot of time setting up Nix and NixOS to replicate my current dotfile environment on Debian I've spent years developing and which I can deploy on a new machine with a one liner. I really like Nix and found their DSL fairly easy to pick up, I didn't keep it for my desktop, workstation, or servers though for a few reasons.
1) Package availability: this is by far the largest reason. I frequently need to use software or specific versions that are just not available and while I did create some packages myself it is just too much work when I need to get something done.
2) Language Documentation.
3) I still need to use cargo and pip anyway.
4) Even when packages were available they often lacked the configuration options I needed and I would have to fork and edit them anyway.
I do think Nix is a lot better than current systems though.
Also a Nix/NixOS user/contributer. I feel like Nix+nixpkgs could become the universal packaging solution adapted to build deb, rpm, etc packages.
Through nix-env it even already has the idea (albeit discouraged) of imperative package management like apt.
Having spent a while with NixOS, running containers for user applications seems like using a cannon to kill a fly. The 'simple' alternative is to drop FHS altogether - which containerization is kind of doing in a roundabout way by isolating the app filesystem from system fhs.
As for it being for developers only... I get that perspective. Debian/Ubuntu packaging is also hard, AUR packaging has its quirks. A lot of this is hidden behind the package manager, wheras with NixOS it is more obvious.
The killer idea for NixOS would be to make package management for Joe Q Public as easy to use as apt while. Tools like MyNixOS[1] are emerging which might bridge that gap.
The main issue when it comes to using Debian or most conventional package managers (nix really deserves its own mention there) is that you also pretty much distro lock your software, which may not be always beneficial. Another problem comes now in the form of distribution; packaging is one thing, distributing is another. Debian isn't too bad about this but depending on your choice of packager[0], you could suddenly need to spend another couple days trying to figure out how to even host the thing unless you want to spend time running wget on your production machines to pull in deb/RPM/makepkg output/pick your poison files.
Nix deserves its own mention because while it pretty much singlehandedly tries to solve all major issues with dependency management, it also... does so by abandoning almost every assumption most people have about how the OS is supposed to work (not to mention that writing nix files is basically learning a whole new language which is... doable but not exactly accessible). It's definitely the stronger solution compared to dockerfiles, but you can translate any program for any distro into a dockerfile as long as it runs on your kernel (alongside the fact that a dockerfile is a really good way to deal with the "documentation abandoned 5 years ago, but it runs on Dave's machine if you follow the README and change about 50 different small settings in your OS" projects which are done a dozen with FOSS projects).
Docker is a mess technically but when it comes to software you want to use/deploy but don't want to understand all the fine details of the source code, it is often a lot easier to work with compared to Nix, which if you have something not in nixpkgs, can result in you needing to start making upstream patches to genericize build directories and generally change peoples CI flows in ways maintainers don't necessarily appreciate.
tldr; nix is good, docker is easy.
[0] It's been a few years but the worst package distribution system I've had the displeasure to use are Ubuntu PPAs. It's a system close to the Debian specification but it requires a whole set of separate commands and weird signing steps before you can upload anything, none of which is properly documented because they expect people that want to use PPAs to shove it in a makefile, which isn't useful if you don't use a language that relies on Makefiles, but I digress.
Most of the unix package management systems are not really that good for development: they don't support sandboxing, or non-root installation/execution, or don't support the right kind of versioning, or don't support multiple versions of a library, or some other issue.
The only existing system that I might trust enough for this kind of thing Nix, and at least for Haskell it is a pretty solid alternative to their language-standard package manager. Unfortunately, its popularity is way lower then stuff like apt or yum which are pretty shitty for development compared to something like pip or cabal.
As TFA itself answers, "no". But I can give a different reason: nix is too much of a barrier of entry, relative to Docker.
Docker might not be simple; there's a lot of moving parts to manage, some hidden gotchas, and networks are a mess. But it's comparatively easy, and once you bake an image, it's pretty simple. Dockerfiles are basically just sh. Package managers are the usual suspects. Images are easy to distribute. It's very familiar.
Nix is not easy. It's a new syntax to learn, it's a new way of building, it's an entirely new way of thinking about the problem. But in the end, it does simplify packaging in the Rich Hickey sense of the easy/simple dichotomy. No braiding of packages and shared libs. But using Nix is not so simple. There's all kinds of bindings and bodges and bespoke shims to make it all work.
History tends to show that easy+non-simple things beat out simple+non-easy things (devs are lazy). Easy-kinda-simple vs non-easy-kinda-simple-but-long-term-gains? No contest in my opinion.
I think Nix is a beautiful idea but it's an uphill battle.
I think the way to look at this is that Nix allows users to decide what kind of image they want.
If I want a smaller package than what the official package offers, I can do just that. Just create a new package on the fly by extending existing package definitions. Disabling features, adding compile flags, dropping dependencies, patching the source of existing packages is very easy to do in Nix. With Debian or Alpine, I have to rebuild software from scratch if some package doesn't fit my needs. With Nix, it's only a few lines of code. For example:
nginx.override { withPerl = false; }
Nix also lets me choose what I want or don't want to include in my image. A Nix built image is just another Nix "package," so it has enough information to include only
the things I need. Docker can't do that because it has no insight whatsoever about files included in an image. So I'm left guessing which files are needed and which aren't and have to tediously copy those in a completely new image.
Finally, Nix lets me choose how I want to run my applications, including if I even want to run them in containers or not. Way too often, Docker-native applications becomes so tied to the image that it can't be run any other way. If I want to change some aspect of the environment that an application runs in, I have to fork the whole thing. Worse, when it comes to building Docker images, there are no reproducibility guarantees. With Dockerfiles essentially being no more than a shell script to make tarballs, they're very much a "works in my environment" way of building software.
I've actually been exploring nix myself recently. It has some interesting features. I'm finding it quite nice to maintain some C-based packages across both Linux and Mac OS X (where it is somewhat of a competitor to Homebrew).
I've been trying to get it to manage some Ruby applications, complete with gems, private github gems, etc. This has been difficult, in part because some areas of nix are a bit rough, and in part because Rubygems has incomplete dependency information (i.e. there's no standard way to know that, say typhoeus gem depends on C library libcurl, and I'm still unclear on how/if dynamic loading can be made to load the nix packaged libcurl).
Something like nix is what I had in mind with my original question. I'd like to see new languages at least design their custom package managers with these more generic systems in mind. Rubygems has some quirks, and Bundler just includes everything and the kitchen sink (sourcing gems from local files, github, various other features) that complicate matters.
Nix is good for keeping things more or less isolated and tracking complete dependencies, though an alternate way to accomplish similar is something like Docker and then just scripting all the native package managers...
Nix isn't a package manager, it's a system for making ad-hoc, repeatable computing environments.
The "package manager" paradigm doesn't fit Nix that well, which is why it's a painful experience when you come to it from the angle that it's another Linux distro.
(IMO it makes more sense to think of Nix as "declarative Docker that doesn't need Linux namespaces".)
I think that's part of the problem. It seems like the only way to have a good nix experience is to go all in with NixOS. The problem is that is a huge sell for someone who already has an OS they like and the fact that testing out nix standalone is such a pain means you end up with very little confidence in the prospect of migrating everything over. Plus, at least when I considered NixOS a few years ago, the setup instructions seemed not well ironed out and made me really hesitant that it wouldn't brick my system.
All in all I think nix falls into the category of great idea in theory, but the implementation is so lacking in ergonomics and ease of use that I don't see how it could be anything other than a niche build system without major UX updates.
But it seems it isn't able to blindly mirror stuff from pip, for example? Or to just package any linux under the sun, like Docker can? You'd have to have a nix-specific version of every package you want to use.
And then, the first time you hit upon a package it doesn't have, you have to develop and maintain your own version of it (as far as I understand?). This sounds like a lot of work for someone who wants packages to just work, so they can focus on other things.
I remember using freebsd at some point. The annoyance of not being able to just grab a deb from random sites and install them far outweighted any benefits I got from a cleaner OS organization and some extra features. Nix feels the same way.
I am not saying nix is a bad idea or that it'd have no benefit. Just that, for non-enthusiasts and non-early adopters like myself, it's dead in the water until there is some major support behind it.
reply