Hacker News new | past | comments | ask | show | jobs | submit login
One Week of NixOS (jae.moe)
247 points by jaemoe on Nov 8, 2020 | hide | past | favorite | 179 comments



Nix is a nice research project, but after playing with it for ~6 months and contributing to nix-packages, I came to conclusion that (in my case) it's not suitable for production nor development, and now I manage my personal machines with a simple Ansible playbook.

Main reason for leaving was that Nix package maintainers have to heavily patch all software. Packaging for nix is more like porting software to another operating system. Just check the amount of ad-hoc patches in nix-packages repo, and note that they have automated tools for patching the most common problems, so the problem is even worse. Now how about quality of these patches... I was able to merge some pretty large patches to nix-packages from an anonymous and sketchy-looking github account, and they weren't scrutinized much, because the original author of the derivations abandoned them.

Moreover, Nix breaks the chain of trust for the language packages. For example, Erlang and Elixir packages are signed cryptographically. Most erlang libraries come with a rebar.lock file containing hashes of the dependencies, so reproducible builds are already ensured. Unfortunately, package hashes are incompatible with Nix derivation SHA's, because they include some additional envelope data. What did Nix people do to work around this problem? They patched out the checks for rebar.lock files from the 3rd party Erlang build system. I would not dare to run a distro that contains patches like this in any kind of production environment.

Additionally, /nix directory is readable by all users, so you cannot use Nix to manage secrets, and there was no universally approved way of doing so (or at least it was the case at the time I was using it).

As for personal use... You cannot install opam packages without dealing with incompatiblities, you cannot easily install games from Gog without dealing with incompatibilities, and to be honest, do you really need such degree of reproducibility for your very own dev machine?


As said by the other commenter, most of these patches are caused by NixOS not using the FHS (except for /usr/bin/env), which can be considered as a good thing in itself. In an ideal world, it would not be a problem (programs should not assume anything about the filesystem hierarchy, and should always use $PATH or their own environment variables).

The issue of integrating with other language ecosystems is indeed very problematic (and it's a very hard problem), especially with regards to the chain of trust (by the way, it's not completely broken, you can still read the original package hash in the derivation, and evaluate this derivation to get the Nix derivation hash), and with regards to the fact that including all of the packages of every ecosystem in `nixpkgs` is not doable.

There is also the (related) problem that evaluating a configuration implies evaluating `nixpkgs` itself, which requires a good amount of available memory, and this can only get worse as `nixpkgs` grows.


I don’t know about Erlang but typically language-specific packages are handled with a tool that converts from the language-specific package management system into Nix, and that tool will do whatever validity checking you normally expect from the language package manager. For example, for Ruby, it uses bundler under the hood which will use the Gemfile.lock, and then it converts the results of that into Nix expressions.

Someone could certainly submit a PR to the nixpkgs repo that purports to do that but really modifies the generated Nix expressions to refer to different sources, but this would be discovered by anyone who re-runs the package update process.


I maintain several Nix packages, and I agree that for some edge cases it can be a pain.

Another annoying thing is that NixPkgs has developed some technical debt, with some packages being perennially broken. Guix is smaller, but much cleaner in this regard. Julia can't be used in Nix, and many Bioconductor packages are broken.

However, I feel like the existence of FHSUserenvs needs to be better advertised and documented. These give you the ability to easily install unpatched software that assumes a regular (FHS) Unix filesystem layout (/bin, /lib...).

Still, I think the benefits of using Nix and NixOS surpass the drawbacks right now. I use Nix in dozens of machines. It is, along with Arch, my favorite distribution. Both sit at two local maxima of the design space. Declarative-functional and imperative with a minimal layer of tooling.


If you had to go with one or the other, which would it be? I'm on the fence now, I have one machine with Arch, my heavy development machine with NixOS. I'm considering ditching NixOS altogether.

I just miss using the same tooling as everyone else in my team without issues or having to constnatly spawn up a new nixenv everytime I change folders. Maybe using FHSuserenvs will help?

I've never really been able to grasp the language, I don't care what anyone says, the documentation is terrible. Every time I try build a package it always takes me days to workout how to do it.

Really feeling that while, yeah, it's nice to have everything in one configuration file, it's good, but when something breaks, I have really no idea how to fix it.


To be fair, the packages have to be patched because many applications assume FHS.

The fact that Nix ditches FHS is so what's appealing about it unfortunately there's a huge body of work that assumes it.

Most of the patches though are making libraries or binaries fully referenced from nix store rather than from the PATH or some other implicit state.


What is FHS?


> The Filesystem Hierarchy Standard (FHS) defines the directory structure and directory contents in Linux distributions.[1] It is maintained by the Linux Foundation.

https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard


> Nix is a nice research project

It's not. As far as I can tell, it's used heavily in some corporate environments once you're faced with solving the development environment dependency hell and you need something that actually solves your problem. (This is my story too.)

> ...and now I manage my personal machines with a simple Ansible playbook

Where Nix is used you typically don't have "personal machines". And having a separate guy just doing setups of developer environments is a huge overhead.


I have traditionally used ansible and I hate it and am slowly converting to nix tooling.

With ansible, I feel like everything is poorly solved and you need to weigh decisions about when to use various hashicorp products. Worse still if you use their plugins instead of just script substitutions you get stupid behavior like not being able to fix your configuration because it is broken, or turning off the supposed advantage of these plugins such that they are almost as good as sed again.


I've used ansible for years to configure my local workstation and hundreds of linux servers both on prem and in AWS and have never needed a Hashicorp product.


I don't find myself patching stuff all the time, and would hate to go back to half-assed leaky-abstraction kludges like Ansible.

But I do agree we need to deal with the language-based packaging situation much better. It's a long-standing project of mine to fix that.


> I don't find myself patching stuff all the time, and would hate to go back to half-assed leaky-abstraction kludges like Ansible.

Speaking of half-assed kludges, NixOS itself is a held together by duct tape of scripts patching shebangs and whatnot.


Those are kludges, but they are nicely confined to build time.

The deployed system is very easy to reason about, which I greatly appreciate with my laptop and production environments.

(In addition to trying to support the language-based ecosystems better, I also want to reduce the things we do in bash. I think those are complimentary goals, too.)


> They patched out the checks for rebar.lock files from the 3rd party Erlang build system.

Oh ffs really? Yeah, that's the kind of hijinks that leave you scratching your head. Thanks for the head's up.


No, the commenter is grossly misrepresenting the facts here, as is the case with every other point being made in that same comment. The patch in question disables the ability to fetch packages from online sources, requiring you to specify the URL of the required packages and its hash beforehand. Plus, it's not even meant for general use and instead is meant to help with packaging for Nix. For general use, you can very easily use the unmodified build instead.


Cheers

I'll admit (although it annoys me) that I couldn't follow what was going on there. Nix x Erlang's gnarly build system seems like complexity junkie crack to me, but then I'm getting older.


I too initially assumed the commenter was being honest, and it took me a while going through code, commit history, and GitHub issues to realize that this wasn't the case.


> Erlang's gnarly build system

It's actually fine, thanks for a remark.


> requiring you to specify the URL of the required packages and its hash beforehand.

...a different hash.

You see, I naively think that a checksums should not be overwritten when they doesn't match.


That's not what I said. It's not about replacing hashes.


> Oh ffs really?

Yes, really. This PR partially reverted this behavior (or rather made it less intrusive): https://github.com/NixOS/nixpkgs/pull/54115/files , but from there you can easily track "rebar3 hermecity patch", which had introduced it.


Egad!


You just saved me a ton of time. I wanted to investigate if I should try Nix but this is not going to fly. Thanks for the detailed comment.


Almost every point being made in that comment grossly misrepresents the facts and/or leaves out key details. For specifics see this comment[1].

If you're curious about Nix, I highly recommend you give it a try. nixpkgs have great quantities of packages that matches Arch/AUR, and every single one of them goes through mandatory reviews ensuring quality. On top of that, the Nix tooling makes it easy to create your own packages and reuse existing package definitions. So for example, if you want to use a fork of a software available in Nix and maybe even add some custom patches, all you need to do is write a few lines in your config. Switching to Nix was a really refreshing experience and the amount of documentation and the code in the nixpkgs repository was very helpful for me to get started.

[1]: https://news.ycombinator.com/item?id=25030546


Plenty of us do use it on our own machines and in production, and it doesn't seem like a never-ending packaging war.

Most software actually doesn't assume the FHS. (Autoconf, Meson, and CMake all don't, for example.)


> Main reason for leaving was that Nix package maintainers have to heavily patch all software.

Any widely used distros do this. Plus, the statement that you have to patch all packages is false. In many cases, all you have to do is set the right build flags and environment variables, which is handled by standard helpers in nixpkgs.

I'd also like to add that nixpkgs has the most extensive testing for packages compared to any other distros I've seen.

> Packaging for nix is more like porting software to another operating system.

Dramatic, but again, simply not the case.

> note that they have automated tools for patching the most common problems, so the problem is even worse.

This is a good thing. Manual patching for the most common problems isn't sustainable, especially if you maintain a large number of packages. Just ask packages maintainers of any major distros.

> I was able to merge some pretty large patches to nix-packages from an anonymous and sketchy-looking github account, and they weren't scrutinized much

All packages in nixpkgs has a mandatory review process as you should very well know. As scary as you make it sound, I'm pretty sure at least one committer have taken a look at your code to see if there was anything malicious in it.

> Moreover, Nix breaks the chain of trust for the language packages.

After a quick look, it seems like you can still use the unmodified erlang package manager? The patched version you've mentioned seems to be there for facilitating creation of Nix packages and it looks like the main intent was to remove the ability to download packages from the internet. If this is the case, it wouldn't be a security problem at all because the dependencies would have to be prefetched and their hashes precomputed.

> /nix directory is readable by all users, so you cannot use Nix to manage secrets

Why not store secrets in a private location, just like you would on any other distros??? What is it that other distros have that Nix is missing? I'm not seeing your point here.

With that being said, note that this feature is being worked on, and systemd very recently introduced a new feature for secrets management [1].

> You cannot install opam packages without dealing with incompatiblities, you cannot easily install games from Gog without dealing with incompatibilities

Matbe take a look at buildFHSEnv.

> do you really need such degree of reproducibility for your very own dev machine?

Yes, it saves me from having to do a clean install of my system every few months. I haven't done a clean install at all the last few years since I started using NixOS.

[1]: https://github.com/NixOS/rfcs/pull/59#issuecomment-624723733


> Any widely used distros do this.

I've yet to encounter another distro that deliberately breaks 3rd party software the way Nix did it to rebar3 (before it was reverted).

> Plus, the statement that you have to patch all packages is false.

IIRC `patchShebangs' script runs for any package using stdenv.

> I'd also like to add that nixpkgs has the most extensive testing for packages compared to any other distros I've seen.

Which distros? Can you share a comparison in number of tests/coverage?

> Dramatic, but again, simply not the case.

As other commenters mentioned, software written for GNU\Linux often assumes FHS. NixOS breaks FHS, and has to patch soft to work around that.

> This is a good thing.

How so?

> This is a good thing. Manual patching for the most common problems isn't sustainable, especially if you maintain a large number of packages. Just ask packages maintainers of any major distros.

Other major distros don't break FHS, therefore they don't need to patch trivial things like shebangs.

> All packages in nixpkgs has a mandatory review process as you should very well know. As scary as you make it sound, I'm pretty sure at least one committer have taken a look at your code to see if there was anything malicious in it.

It depends on your threat model. Mine is stricter.

> If this is the case, it wouldn't be a security problem at all because the dependencies would have to be prefetched and their hashes precomputed.

Once again, it breaks the cryptographic chain of custody set by the upstream. In my threat model that's not acceptable. I tend to trust the upstream more than the distro.

> Why not store secrets in a private location, just like you would on any other distros???

Secret provisioning is by far the most difficult DevOps problem, and it can go catastrophically wrong for all too many reasons. Nix not only doesn't help, but also introduces additional footguns with world-readable configuration files.

> What is it that other distros have that Nix is missing?

Other distros have FHS. FHS accounts for secret management, among other things.

> Yes, it saves me from having to do a clean install of my system every few months.

Ok, though I never had to do a clean install of GNU\Linux either on my dev machine.


The fact that they reverted the rebar change suggests that or wasn't intentional.


> I've yet to encounter another distro that deliberately breaks 3rd party software the way Nix did it to rebar3

Except that your anecdote is completely misleading given that the patched version was intended for creating Nix packages. You could've just used the unmodified version instead.

Furthermore, upstream developers complain about how distros are breaking their software all[1] the[2] time[3]. Again not a Nix specific problem. Nix even alleviates some of the problems because you can use different versions of the same software, meaning that different packages don't have to share dependencies as aggressively as other distros do.

> Which distros? Can you share a comparison in number of tests/coverage?

Arch, Debian, CentOS, and Homebrew, though the last one isn't strictly a Linux distro. I can't possibly count the numbers given that the sheer number of packages available, so it's based on experiences at looking at package definitions. I tend to check package definitions across distros a lot to write packages fir Nix.

> It depends on your threat model. Mine is stricter.

If you have a problem with software projects accepting outside contributions even if they go through review, you have a problem with using free and open source software in general. It makes me wonder how you even manage to use the Linux kernel.

> Once again, it breaks the cryptographic chain of custody set by the upstream. In my threat model that's not acceptable.

Then use the unmodified rebar3 for your project instead. But anyways, if your threat model involves not trusting SHA256, you likely have a problem with your said cryptographic chain of custody too.

> Nix not only doesn't help, but also introduces additional footguns with world-readable configuration files.

> FHS accounts for secret management, among other things.

That's an outright lie. NixOS doesn't prevent you from storing secrets in a file and applying your usual UNIX permissions. FHS has absolutely nothing to do with it.

[1]: https://github.com/pypa/pip/issues/5599 [2]: https://web.archive.org/web/20181021091049/https://github.co... [3]: https://twitter.com/videolan/status/1153963312981389312


> Except that your anecdote is completely misleading given that the patched version was intended for creating Nix packages. You could've just used the unmodified version instead.

The package was called rebar3, not rebar3-nix or something. If the fork was called differently then no one would complain. Also this fork was based on hacks, like patching rebar3's internal files and messing with caches. If you don't see anything wrong about this, then this way of thinking just proves what I said in the parent.

But forking rebar3 wasn't needed at all, because rebar3 _already_ had all the features needed for Nix. Namely, it has get-deps command producing fixed output derivation, and it supports _checkouts directory, needed for hermetic build.

> Then use the unmodified rebar3 for your project instead. But anyways, if your threat model involves not trusting SHA256, you likely have a problem with your said cryptographic chain of custody too.

There's no reason to use SHA256, if you just replace it with a different SHA256 whenever it doesn't match with the upstream.

> Nix even alleviates some of the problems because you can use different versions of the same software, meaning that different packages don't have to share dependencies as aggressively as other distros do.

Docker exists. Although it's not perfect by any means, it doesn't require reinventing the entire world. I extrapolated my experience with Erlang to the rest of NixOS reinventions, which in theory could be wrong, but it was convincing enough for me.

> That's an outright lie. NixOS doesn't prevent you from storing secrets in a file and applying your usual UNIX permissions. FHS has absolutely nothing to do with it.

I was not talking about "storing secrets in a file", but rather about the whole live cycle of the secrets, including transferring them between parties, storing, provisioning, rotation, etc (imagine you have to solve a problem of changing some secret on 100 machines securely and reproducibly via blue/green deployment). As far as I know, Nix doesn't provide facilities for solving this problem at scale. I would be happy to be proven wrong.

> FHS has absolutely nothing to do with it.

It absolutely does. Some pieces of software look for secrets in /etc/ (Kafka, for example). When etc (or its analogue in /nix) is world-readable hilarity ensues.


> The package was called rebar3, not rebar3-nix or something. If the fork was called differently then no one would complain.

First of all, the fork obviously isn't there for general consumption. You made it sound like unsuspecting users would use it and have unverified code downloaded on their machines, which is borderline false when it doesn't have the ability to download code from online sources. This attempt to mislead is what I'm having problems with.

Second, it would've been nice if you've raised an issue on GitHub and helped improve Nix instead of complaining and spreading borderline falsehoods on HN. Erlang isn't exactly a widely used language, so design choices would be made by the few who actually uses it. It would always help to have more productive input by actual users.

> Also this fork was based on hacks, like patching rebar3's internal files and messing with caches. If you don't see anything wrong about this, then this way of thinking just proves what I said in the parent.

Ranting about how "it's a hack!" based on cherry-picked implementation details isn't convincing at all. The intent here is to have a copy of rebar3 that builds packages from local sources only, for consumption by package maintainers. That's not by any means unreasonable.

> But forking rebar3 wasn't needed at all, because rebar3 _already_ had all the features needed for Nix.

Tell me a single major distro where it's okay to essentially redistribute packages from language-specific package managers without making huge adjustments in the way packaging is handled. I know of none. For countless software, distros just give up on packaging altogether because the effort required to make that adjustment can easily get out of hand. This is the major reason many Maven packages aren't packaged on Debian.

To make matters worse, many packages from languages-specific package managers won't even compile on major traditional FHS compliant distros. Changes to upstream packaging aren't unwarranted, however much you'd prefer to believe otherwise.

> There's no reason to use SHA256, if you just replace it with a different SHA256 whenever it doesn't match with the upstream.

The SHA256 would be verified by package maintainers, reviewers, and the hydra CI instance.

> Docker exists.

If you're against the concept of distro-provided packages, why didn't you say so upfront instead of making baseless accusations about what a horrible security disaster Nix is?

Also let me remind you that almost all Docker container images rely heavily on distro-provided packages. What are you going to do now?

> As far as I know, Nix doesn't provide facilities for solving this problem at scale.

Neither do other distros, though Nix is a close to having a built-in solution as I've just shown you.

> When etc (or its analogue in /nix) is world-readable hilarity ensues.

Why are you repeating this when I just told you it's not true? /etc in Nix is not world-readable, plain and simple. This works perfectly fine on my NixOS system:

    $ echo secret | sudo tee -a /etc/secret > /dev/null && sudo chmod 600 /etc/secret    
    $ cat /etc/secret
    cat: /etc/secret: Permission denied
    $ sudo cat /etc/secret
    secret


> First of all, the fork obviously isn't there for general consumption.

I didn't know that when I installed a package called "rebar3" and spend some time trying to understand what's wrong with my build. Oh, my bad, should've known better that "rebar3" was for internal consumption, and I need to install "rebar3-open" instead.

> Second, it would've been nice if you've raised an issue on GitHub and helped improve Nix instead of complaining and spreading borderline falsehoods on HN.

Thanks for suggestion. I did exactly that, and I fixed this entire mess. In fact, the current NixOS Erlang infra is partially based on that work.

> Ranting about how "it's a hack!" based on cherry-picked implementation details isn't convincing at all.

I professionally work with Erlang, and I know what is hack and what is not.

> Tell me a single major distro where it's okay to essentially redistribute packages from language-specific package managers without making huge adjustments in the way packaging is handled. I know of none. For countless software, distros just give up on packaging altogether because the effort required to make that adjustment can easily get out of hand.

Language-specific packaging should be left to language-specific package managers, they have more domain knowledge. Nix doesn't solve this dilemma in any better way.

> Also let me remind you that almost all Docker container images rely heavily on distro-provided packages. What are you going to do now?

Keep on using it? Take systems software from the distro-provided packages, add my own stuff on top. Building RPM is a nobrainer. I was considering Nix as an alternative to our deploy process, but realized that it would introduce more problems than solve.

> /etc in Nix is not world-readable, plain and simple.

Please take a closer look at what you're quoting. You missed a very important part:

> (or its analogue in /nix)

You see, if I want to utilize Nix to full extend and use its main "reproducibility" feature, I need to put all my configuration in a derivation. Configuration includes secrets. Derivations are world-readable.

> Neither do other distros

Distros maybe don't, but "bug-ridden kludge that is Ansible" (according to Nix user) does.


> Oh, my bad, should've known better that "rebar3" was for internal consumption, and I need to install "rebar3-open" instead.

If that was your problem, you should've said so instead of spinning it up into an entirely different security problem that plainly did not exist.

> Thanks for suggestion. I did exactly that

Except you didn't stop spreading falsehoods. You've spent more lines using your brand new HN account spreading lies about an open source project people have dedicated their free time into.

> professionally work with Erlang, and I know what is hack and what is not.

Fixating on hyper specific implementation details taken out of context without considering the design, intent, and usage is not what I call professionalism in the software industry.

> Language-specific packaging should be left to language-specific package managers, they have more domain knowledge.

Domain knowledge that fails to build or run portably even on widely used FHS-compliant Linux distros.

> Nix doesn't solve this dilemma in any better way.

I've already explained about the problems distro package maintainer faces and how Nix alleviates some of the problems which you then responded with a totally unrelated "Docker exists" nonsense.

> Take systems software from the distro-provided packages, add my own stuff on top.

So packaging problems won't exist if we just stick with Docker, but you would use distro packages to create a Docker image? How would that even work?

> Building RPM is a nobrainer.

Go tell that to RedHat maintainers.

> Please take a closer look at what you're quoting. You missed a very important part: > > (or its analogue in /nix)

/etc in NixOS is not /nix. It's /etc. Very important indeed.

> You see, if I want to utilize Nix to full extend and use its main "reproducibility" feature, I need to put all my configuration in a derivation. Configuration includes secrets. Derivations are world-readable.

You see, Please. Stop. Repeating. Lies.

You don't put secrets in a world-readable location, period. The typical Nix way of handling secrets is that you store in them in a secure path and point the configuration to that path.

> Distros maybe don't, but "bug-ridden kludge that is Ansible" (according to Nix user) does.

You can use numerous solutions that can work together with Nix. How about NixOps, which, among other things, handles secrets management? Or what about, say, Ansible? After all, any solution that would be able to send the Nix configuration, place secrets in a secure filesystem path, and run commands to build the Nix configuration would suffice.


> If that was your problem, you should've said so instead of spinning it up into an entirely different security problem that plainly did not exist.

It was merely an answer to your remark about "this fork wasn't meant for external consumption". Please don't try to substitute the argument.

> Except you didn't stop spreading falsehoods. You've spent more lines lying with your brand new account on HN.

I spent much more time researching this project and trying to figure out the least ugly way to fix its problems. This time was effectively wasted. I just wrote my post so someone who faces issues similar to mine will investigate the matter more carefully.

> Fixating on hyper specific implementation details taken out of context without considering the design, intent, and usage is not what I call professionalism in the software industry.

Ad hominem, moving on.

> So packaging problems won't exist if we just stick with Docker, but you would use distro packages to create a Docker image? How would that even work?

I am not going on to explain how to work with docker, it's a mainstream technology that has plenty of documentation and examples.

> You see, Please. Stop. Repeating. Lies.

https://github.com/NixOS/nix/issues/8

Please don't go ad hominem and don't accuse me of lying. This issue is submitted by Nix devs themselves.

> The typical Nix way of handling secrets is that you store in them in a secure path and point the configuration to that path.

And this is precisely the hack I was talking about. Because of this approach you cannot manage secrets with nix at scale (just to clarify: when I say "nix" I always mean the package manager). This is an issue submitted by core designers.

I think we ran out of productive arguments in this conversation.


Agreed, the language support situation is a very mixed one in nixpkgs, where support ranges from rudimentary (or even non-existing) to well integrated and supported. Particularly the Erlang/Elixir situation is - as you already brought up a while ago[1] - very rudimentary and really needs to be improved.

Right now, I do manage my Erlang dependencies with Nix only and without using rebar/mix (particularly since I do want full release upgrades with hot code reloading), but manually managing those dependencies certainly doesn't scale well for all projects, especially if they already use rebar/mix.

I also haven't looked into newer projects like nix-elixir[2], but as another commenter here mentioned, there are typically tools available to convert between the language-specific package managers, but they all come with their own set of issues and tradeoffs (eg. duplicating dependency information or importing from other derivations at evaluation time) so they might not be suitable for your project.

The situation with secrets is a long lasting issue[3] with several attempts of solving, but so far the best practice is to just to either leave secrets out of the Nix store or just make sure the entire Nix store is not accessible.

Since I also use NixOS for a few days, I can imagine why it could be frustrating if things don't work out of the box like on other distros. Having had my own adventures patching things like no tomorrow, I know sometimes the effort to do this could be quite time consuming, especially the GOG games[4] you mention.

So I'd say if you frequently use software that is problematic on NixOS and don't want to go through the hoops of patching or making workarounds like eg. Docker or FHS user environments[5], I'd probably stay off NixOS.

Personally however I think it is worth going through a few hoops, since to me it shifts the frustration of "my system broke during an update" to "just want to get X to work NOW" and among other nice benefits (eg. bisecting whole systems, rollbacks and/or using specific packages before they broke) I'd rather prefer a working and reproducible system.

[1]: https://github.com/NixOS/nixpkgs/issues/53834

[2]: https://github.com/hauleth/nix-elixir

[3]: https://github.com/NixOS/nix/issues/8

[4]: https://github.com/openlab-aux/vuizvui/tree/0aa8064087b895d2...

[5]: https://nixos.org/manual/nixpkgs/stable/#sec-fhs-environment...


Thanks for a constructive comment.


My favorite feature of NixOS is cleanliness.

I never need to worry about a mess anywhere outside of `/home`. Ever.

Ever make a symlink to fix a broken package and forget about it?

Ever make a change to a config file and forget about it?

Ever update your system and find out something is broken, just to spend time repairing the problem?

All these things tend to add up over months and years. After a while, I usually end up reinstalling my distro to start fresh.

Never again.


I use NixOS for the same reason. Cleanliness is empowering.

I used to have diskless machines on my network set up the non-nix way: system directories full of tftp and pxe stuff; root directories constructed by an OS's installation procedure, and then customized somehow to work with an nfsroot. Later on, I wanted to make some changes but had no idea how. I hadn't taken enough notes of where everything came from and what it was doing. The files were still working, but without having documented their intent, I had to scrap it all. But documenting intent is laborious and fragile; you have to include enough detail that future you (or someone else) can follow your logic, and worse: keep all that in sync with the reality.

Since then I have fully committed to the Nix way. Now, the contents of my tftproot are built according to a declaration in my configuration.nix: the root directory in my TFTP configuration specifies a dependency on a PXE package, with some configuration applied. Not only don't I have to look through the built directories and try to remember what everything is, I never think about the built directories. The insight of declarative configuration is: if you fully document your intent, the system can take care of realizing it.

When I want to change a program I have written, I edit the source code (where all the intent is) and recompile it. NixOS is that for systems. I will no sooner go back to mutation-based system management than start changing my programs by taking a hex editor to the binary.


I've been using NixOS with home-manager and it's been a really nice experience because of this. Now I can keep my desktop and laptop pretty much in sync by just tracking 2 small git repos instead of having a log/script of all the config tweaks on /etc that I needed to do on random files.

And it gets better over time, more projects are supporting Nix, and there's exciting things being worked on, like IPFS support for the store, and Flakes to get proper reproducibility.


And even when you do screw things up, like accidentally deleting things in the Nix store, it's quite easy to recover as well.[0]

[0] https://nixos.org/manual/nix/stable/#sec-nix-store


On the other hand, getting some apps to work can be a bit of a pain with NixOS. Especially binaries and/or Steam games, things running through Wine can be a pain because standard libraries are in non-standard locations.

What I ended up doing since about a year or so is just make my whole root partition something I can generate with Debian debootstrap + chroot. I have a +- 250 LOC bash script which I just invoke on a free partition, and it just completely reinstalls Debian in there as if it were a Docker container.

I then rerun this about once every month, reboot, switch to the new partition (and fall back to the old one in case things went wrong, which almost never happens) and I couldn’t be happier with it. Happy middle ground.


> Especially binaries and/or Steam games, things running through Wine can be a pain because standard libraries are in non-standard locations.

Steam just works, though? I've been running nixpkgs.steam for a while, and it has consistently been the best Steam-on-Linux experience I've had. Precisely because what Steam sees is tightly controlled, and there's no place for accidental DLL/.so hell, and ambient changes to your OS making it into Steam/games breaking its assumptions.

(and for everything else you have steam-run/buildFHSUserEnv)


Steam itself works pretty well, but I've had many games just inexplicably segfault on startup. It's weird because I get the same segfault: - using steam-run - in a FHS user environment - in an LXD container (on this NixOS host) running Debian 10

The same games run fine on a Debian 10 host, all of the libraries the link to are bit-identical to the ones in the LXD container, and I've even tried running the exact same kernel.

I'm lost here, as I feel like I've made everything match (at least in the LXD container): the kernel is bit-identical, the games are bit-identical, the libraries they link to are bit-identical. There must be something I'm missing.


Try strace and look at what the is loaded by ld.so?


Yeah I’m not sure, I recall something with either Steam or the Blizzard Battlenet. I don’t know exactly what it was, but I do know that I spent a day or two trying to relocate objects in a binary application and I ended up just giving up.

Having said this, ostensibly I really like NixOS and I have actually used it as my main desktop for about a year back in 2015.


Have you taken a look at buildFHSUserEnv[1]? In the Mozilla Nixpkgs overlay it is used to package[2] the Vidyo desktop application.

[1] https://nixos.org/manual/nixpkgs/stable/#sec-fhs-environment... [2] https://github.com/mozilla/nixpkgs-mozilla/blob/master/pkgs/...


Fha user environments are great. I just wish they would support supplementary groups. Running programs that want device access is a no-go currently


Sounds like you'd like an OSTree-based Debian.


What’s that, if I may ask?


Take a look at Fedora Silverblue. It uses ostree.


My experience with Nix and NixPkgs is that 95% of the time it's fine. That 5% is a real PITA.

I think nix isn't as useful for developers using it to setup their workstation compared to for operations setting up deployment environments. -- I like that I can just run "nix --install myPackages" and have the exact, up-to-date versions of software installed... but, it's not often that I need to run this. (The up-to-date versions thing is nice). -- Maybe this will be more compelling for stuff like GitHub Codespaces, and other ephemeral machines?

(EDIT: and nix-shell is cool and very pure, but looks to me like people are just fine using images of development environments/toolschains with VMs or Docker. etc.).

NixOS itself does feel very different to other OSs. I think people discount how much trouble they run into on other OSs. Partly because other OSs have larger communities, and advice will often apply across multiple OSs. With NixOS, there's a higher requirement for understanding of what's going on; and it's not obvious that the benefit from doing this is worth it.


On the contrary, I find it super helpful to set up my workstation. I don’t use any other package manager on macOS these days, everything is Nix, fully declarative with a small script that basically does `nix-env --install` (but with the flags to replace my current environment wholly, and with some helpers around showing what changed). I can then just sync my config between my machines and run my script and get identical setups on every machine I use, and I can update all of my packages at once just by running `nix channel --update` followed by invoking my script again.

And there’s a bunch of utilities I use rarely so I don’t even keep them installed, since I know I can just `nix run nixpkgs.hello -c hello` if I ever want to run them.

And then for a work project I set up a custom derivation that I can use when I need to run the occasional scripts that require the custom ruby and python environment, so I can just run e.g. `nix run nixpkgs.my.env -c pod install`. This way I’m not even polluting my global environment with this stuff the way the work scripts expect. And I’m currently working on formalizing this into Nix derivations in the work repo directly (in an attempt to convince my coworkers that we should all use Nix).


"nix is useful for getting the same version of programs on different computers". This is obviously useful to have.

Say for the use-case of "I have a macOS laptop, and I use Arch Linux on a different computer". I can't genuinely recommend nixpkgs as better than just running "brew install..." and "pacman -S" (and whatever AUR tool is in vogue). -- Yes, once you know what you're doing and have a configuration, nixpkgs is nicer. But it's not as if the good-enough alternatives are too hard.

When there are more hurdles to getting the bleeding edge (like on Amazon Linux or whatever), I appreciate how much easier it is to just "install nix, install my packages". But even then, installing a recent version of tmux or fish or whatever is a quick search and a few commands away. (Which isn't that much if you only have to do it once every few months; and/or note how to do it in some script or markdown notes).


I don't understand the "I have a macOS laptop, and I use Arch Linux on a different computer" claim. If anything that's an even better time to use Nix, because it means I only need to know one package manager instead of two. The setup I currently use on macOS could be dropped onto a Linux machine and I expect it would work with zero changes there, or I could switch over to home-manager (probably a good idea, I just haven't done it for historical reasons). And if I don't have a setup yet I could just use `nix-env -iA nixpkgs.pkgname` to install stuff the way people usually get started with Nix.


> I think nix isn't as useful for developers using it to setup their workstation

Trust me, if your development setup is non-trivial (bunch of services maybe in different languages maybe written by different teams) it absolutely is, and is one of the areas where you can get the biggest productivity wins by using nix.


In my experience, how good of a time you’ll have developing in Nix is incredibly tied to what you program in. Last time I tried Ruby was a real nightmare, and I never did manage to get Ruby on Rails to work correctly.


I had the same experience - and to make it worse, I was trying to integrate RubyMine into it.

At some point I managed something that could be launched from nix-shell, only to lose it soon after in FS failure.


Sounds like a good OS for a computer cluster.


I think it’s interesting to compare it to Kubernetes. K8S has more functionality at the cluster level and a stronger ecosystem, but Nix has a much more well-founded “core”, IMO.

Both are declarative by default and easy to reproduce.

Hopefully we’ll see them converge in the future.


It's how they used it at my old job. You could deploy nix with the libs needed for the compute part.


I agree with most of this, but wanted to comment on the "developer environment" part. TL;DR: I feel like you're under-valuing this part?

> I think nix isn't as useful for developers using it to setup their workstation [...] I like that I can just run "nix --install myPackages" and have the exact, up-to-date versions of software installed... but, it's not often that I need to run this.

This might be idiomatic to me (i.e., the devices I use; how; my level of anxiety; etc.) but I have (historically) found OS reinstalls and system moves disruptive.

Over time, the work, documents, downloads, config changes, cruft, old apps and such on a system all congeal into a big blob of system state. To move with confidence, I ended up with a few choices: 1) have the old system runnable as a reference so that I can jump but have it as a reference every time I encounter something that's missing or misconfigured, 2) manually inventory everything on the system to triage what needs to be carried forward and what is crap, 3) copy everything on the system and pretend I'll take the time to do number #2 later (ha! in reality I'll just accumulate multiple nested copies stretching back decades!)

Adopting Nix enabled me to declare my personal essentials, and per-project essentials. This got me close enough to confident I can quickly prepare a fresh device that it motivated me to close most of the remaining gaps on macOS. Instead of feeling like it'd take me days+ to get back to full productivity on a clean device, I know I just need an hour or two.

This confidence liberates me from lot of gnawing everyday anxieties about (i.e., infinite permutations of how inconvenient it would be to lose my system at [already stressful moment where I'm under pressure to deliver something]).

> looks to me like people are just fine using images of development environments/toolschains with VMs or Docker. etc.

I used to be in the VM (virtualbox + vagrant/chef/shell) camp. I was net-happier with that than single-system state and things like virtualenv, but on a laptop I'm not very keen on the extra resource use and performance penalty, and over time I still found one shift or another (virtualbox/vagrant updates, chef cookbook updates, VM image updates, or a VM image that stops publishing) created a fairly regular drumbeat of unexpected, low-leverage debug time.


If you are interested in Nix but don't know too much about it, let me tell you one thing:

You can use the package manager to package, build and install software and to take advantage of their large package repo and features like nix-shell without using the OS. What the OS gives you is a full system and all of its services managed exclusively with the paradigms of the package manager.

I do run NixOS on all four of my machines and I got in OS-first package manager second. At first, like the author, I also frequently needed escape hatches like other machines or VMs, but I think if you get into the package manager first you're probably less likely to get stuck. Depending on what you want to do you get a lot of the good stuff with much less commitment that way.


You can but unless you use NixOS the experience might not be great.

A few months ago I tried migrating my development environment from Ansible to Nix. My playbooks are basically in alphabetical order and so that meant starting with Alacritty. I immediately hit two issues:

- A conflict between the version of fontconfig the package was compiled with and the version of fontconfig installed on my system.

- Nix's OpenGL problem. [0]

They're easy enough to work around but I wonder how big the list would've gotten if I hadn't stopped there.

[0] https://github.com/NixOS/nixpkgs/issues/9415


Using Nix to write packages sucks, but I think the parent is talking about using it as a package manager (I.e., to install packages that others have written), which is usually a pretty good experience.


Using Nix to write packages sucks

Could you explain a bit more what you mean? I had prior experience making Debian packages (on Debian and Ubuntu), Arch packages, and a bit of Homebrew on macOS. When I started writing Nix derivations two years ago, I found that it much easier than making Debian packages. Arch packages were easier than both, because the build scripts are just shell scripts, but I found it easier to make correct packages with Nix.


If I have an app and I want to build it with Nix, it’s typically a lot more work than using my language’s native packaging tooling even if Nix just calls that tooling under the hood. Nix gives me things that my language’s package tooling doesn’t (such as treating my application as part of a larger heterogeneous assembly), but very often that tradeoff isn’t worthwhile (and much to my chagrin because it would be very nice to use a single build tool to manage everything in my project).


Thanks for clarifying. I thought that you were referring to traditional package managers, not language package managers (such as cargo or npm).

I have most experience with Rust/cargo and packaging Rust applications is really easy with buildRustPackage. As a bonus, you can also easily pull in necessary native libraries.

On the other hand, things like Python packages are pretty tricky.

One of the problems is that the Python ecosystem does not have a strong tradition of semantic versioning. For that reason, a lot of Python packages have (perhaps overly) strict bounds. That works fine for something like pip, which can pick any version of a Python package and can typically find a way to resolve all dependencies. But it's harder with Nix, because nixpkgs only ships one version of Python packages (for good reasons).

Another issue with Python packages that I encountered several times is that some Python packages directly modify their own paths (e.g. until recently Huggingface datasets), which breaks with the read-only Nix store.


For using Python packages that are avialable via pip I have been quite happy with [mach-nix](https://github.com/DavHau/mach-nix), which can pull prebuilt python wheels(?) from pip directly. You can also configure it to obtain those packages in other ways, like from source via pip or from nixpkgs. You can also feed it Python packages you have in source code form locally.


I can imagine sitting down and migrating a lot of complex packages to Nix is probably quite a tall order right now. Partially because I think a switch like that is always painful, but also because of the open issues, bugs, yet unanswered questions and usability issues that do exist.

I think it depends on if your use case allows for a gradual transition and on your tolerance for migration pain wether or not Nix is worth the trouble right now.

Even if packaging is more difficult with Nix, I appreciate that packages do end up containing a much more precise and flexible description of what they depend on.


Even many toy applications is painful for one reason or another. For example, even a Python toy app is likely to use a C-extension dependency that hasn’t been packaged in Nix yet, and since C’s ecosystem is a trash fire, you’ll have to figure out how to package it and it’s transitive dependencies in Nix. You have different problems in Go, where you need to provide the hash for the vendor derivation, but the only documented way to get that hash is to run a tool that only works on Linux (and I’m on MacOS). And in whatever case, the documentation for the Nix ecosystem is sorely lacking, so odds are you will have to reverse l-engineer other similar package definitions in nixpkgs to figure out how to make your own package.

Note that these issues aren’t insurmountable, but it doesn’t seem like the Nix community cares very much about them (and of course it’s open source software so there is no obligation for them to care, etc but that doesn’t magically make it a good tool for these use cases either).


I was too. :) Those issues occurred when using Nix on Ubuntu 20.04.


Ah, my bad. Should’ve finished my coffee before commenting...


Were you trying to use Nix for running your graphical terminal on a non-NixOS system?

I have personally worked with Nix on a Fedora system, but only for things that run inside the terminal.

EDIT: I removed some content here because it didn't think it applied since you clarified in another comment you were trying to use existing packages.


This. I think the most powerful ability of Nix is in defining development and deployment environments and the managing of headless machines. Though I do realize that a lot of people love running NixOS as a desktop distribution, I do wish people wouldn't get so hung up on this being the way to "dive into" Nix - it's quite a "deep end" experience and I think it puts a lot of people off.

I would generally advise people to start getting into Nix by using it to define your development environments on your existing (linux or macos) daily OS.


I've been using it for 9 months on laptop. I really love the idea. But had to ditch it and use ubuntu instead, because it routinely turned a 3-minutes-long-operation into 6 hours. I had to do work, not mess with configuration and read 6 A4 pages worth of text only to install some python package.

I strongly feel like it needs to take the idea to a new level, ditch the messy language and completely refactor it. Don't get me wrong, NixOS is 17 years old and it still feels like alpha version.


Wait until you try to write your own package definitions. It’s a completely uphill battle, not least of all because nixpkgs is incredibly difficult to parse as a reference (no static types so good luck guessing what any given function takes for arguments, precious little documentation, no decipherable code organization, few if any direct imports to help you find dependency definitions, etc).


It's not so bad actually. To add a new package there's only two files you have to touch, add a new default.nix somewhere in the pkgs/ tree and add your package to pkgs/top-level/all-packages.nix. Looking at any of the 60,000 packages in Nixpkgs should give one an idea of what to write.


This comment reminds me of the "How to draw an owl" meme:

1. Draw some ovals

2. Draw the rest of the effing owl

Yes, you only have to write your Nix expression code in a couple of files; of course, the issue is "how to write that Nix expression code correctly".

> Looking at any of the 60,000 packages in Nixpkgs should give one an idea of what to write.

This is exactly the fallacy I addressed in my comment--Nixpkgs is a really brutal reference for a variety of reasons. Let's say you're building a Python project--first of all, good luck finding a good reference package in nixpkgs if you don't already know where the Python packages are. Secondly, the general scheme seems to be "import nothing, write some function that takes dependencies as arguments", which means you'll have no import statements pointing you to the source files for the dependencies. Further, because nixpkgs doesn't believe in docstrings or static types, you'll have nothing that helps you infer the shape of the thing you're searching for or otherwise provide you with reliable grep criteria. You'll need to grep for the call site for your function to determine what gets passed in, and that thing might be the result of calling some other function with its own args, so you end up recursing through this process for the whole dependency tree. It's needlessly tedious, and this example is just the tip of the painful iceberg.


This was exactly my experience. They have manuals that are very comprehensive reference texts, but complete lack of structure (no types, no docstrings, no enforced conventions/standards, extremely poor discoverability) makes it a nightmare in practice.


Right, most recently I was looking at the reference for buildGoModule, which produces two derivations--one for pulling the dependencies (e.g., go mod download) and another for building the package. Basically the idea is to avoid re-downloading dependencies if only the package's source code has changed. Anyway, buildGoModule takes a `goModHash` field (or something like that, anyway) which is supposed to be the hash of the dependencies derivation; however, it completely omits any information about how to actually get that hash (and if you think you can just build the package and get the correct hash from the error message, you're mistaken). Googling around a bit online you'll find that you can use nix-prefetch, but it appears to only work on Linux. Note that this quirk is particular to Go, but this is the same sort of thing that you run into all the time in the Nix ecosystem.


and if you think you can just build the package and get the correct hash from the error message, you're mistaken

Actually, you can. In any place a SHA256 hash is required, you can put *lib.fakeSha256" (which is an all-zeros hash) and the build will fail and Nix will tell you what the correct hash is.


Yeah, better documentation is sorely needed in Nix, heck, I can't even look up docstrings in the repl (by default, there is nix-doc[0]. I asked around on IRC about a typechecker for Nix, and people refer me to the Dhall[1] and Nickel[2] projects. Looks like some preliminary work on type checking[3] has been done.

[0] https://github.com/lf-/nix-doc

[1] https://dhall-lang.org/

[2] https://github.com/tweag/nickel

[3] https://www.tweag.io/blog/2017-05-23-typing-nix/


The documentation and language syntax is order of magnitudes better than RPM, though. With RPM, even stuff like commenting out code doesn't work as expected due to parsing quirks and good luck trying to figure out why.


Damn, I was tempted to try it but my laptop needs custom kernel patches [1] in order to work properly.

[1] https://lab.retarded.farm/zappel/asus-rog-zephyrus-g14/


Applying kernel patches in NixOS is actually really easy. Look up the "boot.kernelPatches" option.


Damn, I was tempted by it some time ago and found it required way too much investment, so I thought “I’ll check back once they build enough stuff on top to make most of these tasks easily-manageable without being an expert”. But if it has not happened in 17 years, it probably never will...


I'm not sure it's fair to say because it hasn't happened in the 17 years of NixOS' lifespan, that it never will, when the last 5 years of NixOS have been the most active by large:

https://github.com/NixOS/nixpkgs/graphs/code-frequency


Also, there are some large recent initiatives to improve Nix and NixOS, such as Flakes (which give Nix package sets a standard layout and improves hermatic evaluation). Eelco Dolstra has also presented a proposal at NixCon 2020 to improve the module system's usability:

https://www.youtube.com/watch?v=7sQa04olUA0&t=1h24m18s


> I strongly feel like it needs to take the idea to a new level, ditch the messy language and completely refactor it. Don't get me wrong, NixOS is 17 years old and it still feels like alpha version.

That's what Guix is for. https://guix.gnu.org/


I agree about the language. Guix is in many respects the same as Nix, but it benefits quite a lot by using Scheme instead.


Specifically Guile


A small correction:

> There, we are installing per-user packages because yes, NixOS supports that, any user can have its own packages that others users can’t access.

Other users can access those packages if they want to. Those packages won't show up in other users' $PATH, so other users will not be affected by them, but they could see what's in /nix/store if they wanted to. This matters when you're thinking of putting private data (such as an encryption key) in a package: it's vital that you don't do that on a multi-user system.


I see, thanks for the message! I'll make a small correction.

Edit: Correction published!


I've tried many times. I read the entire manual. I would love to use Nix.

But it's too complex.

I guess that's the result of them trying to do everything an OS does using their new arcane Nix language. I don't know how else this could be accomplished though -- but I hope there is another way.

I find it weird often I would find files written in the Nix language in minified/unreadable way fashion in parts of the system.

It's a sympton of the complexity of everything that for every weird error that I would find I would search the internet and not find a person with the same problem. It's always something slightly different and then the solutions proposed to that person would made no sense to me at all or they would introduce much more complexity.


I don't think the problem is really complexity. It's just the config language.

If you come from a Haskell background its nice, otherwise it's "arcane".

Try Guix-SD.


Actually, unlike most DSLs, the nix language itself is pretty great and can be learned in an afternoon by any competent programmer, no Haskell background needed.

The problem absolutely is complexity, and there is a lot of stuff you need to grok to be able to use nix productively in anger and sadly that includes a lot of stuff that really ought to be much more straightforward.

Also, IMO you don't do anyone a favor by recommending they try Guix-SD over NixOS unless you also make it pretty clear that Guix is quite fringe even compared to Nix. For example Nix can and is being used for Real Work by well known companies. It as a steep learning curve but also, for certain tasks, an enormous payoff that justifies this effort.


> For example Nix can and is being used for Real Work by well known companies

Real Companies are using Guix for Real Work too.

Perhaps Guix is "fringe" by some definitions, but you made it sound like some barely-usable hobby project.

To me, as a former Nix contributor, it largely boils down to a matter of taste. But there are distinct advantages (and disadvantages) to both.


I'd be curious to hear your perspective as someone who is quite familiar with both Guix and Nix. What sort of companies do you know that are using Guix for Real Work (in some significant capacity)? What would be a rational reason for using Guix in production vs nix?

Nix is used by a couple of well known companies such as Pinterest and Target, I have used (and continue to use) nix myself professionally and I know several other places that use it. But even with nix, there needs to be a really good justification to use it in preference to some more standard solution. For example, if all you are working on is python webapp with fairly simple dependencies, I'd probably recommend sticking to poetry and maybe a docker container for your DB. If you need to deal with e.g. machine learning or video processing, or something else that involves a lot of gnarly C/C++/Fortran dependencies or if you've got non-trivial DB migrations or other dependencies which you can very conveniently deal with as a (correctly cached and therefore instantaneous) build artefacts with nix, nix can start to make sense, especially if you need to customize any aspect of the build. At the point where you have a bunch of different services written in several different languages, and your dev env needs to run a dozen plus different services together plus some DB(s) and other infrastructure, you can literally achieve two orders of magnitude improvements in key metrics compared to "industry best practice" cruft like docker or (barf) minikube (e.g. how long it takes to spin up all those services correctly, CI speed, deployment times or how long it takes to spin up a new developer, how much extra tooling infra you need to shepherd and so on). Even then you will still need at least two people with a good familiarity of nix and invest in some basic training for the rest of the company and you might periodically run into annoying speed bumps.

In summary, as a rule of thumb, I'd say even something as non-mainstream as nix only make sense if you think it'll buy you a 10x or greater improvement for something you really care about. I'm not deeply familiar with Guix, but my superficial impression is that it's a much more ideologically pure and not particularly inspired transliteration of nix to scheme that keeps a lot of the obvious flaws in nix (e.g. not using principle of least power; stuff like sha256, github urls and revs should reside in toml or similar and not be munged into the turing complete and non-machine editable nix/scheme code). It still has a significantly lower user base and the greater ideological purity means more stuff won't work compared to nix or mainstream solutions. This all matters less for personal use, where I agree it is indeed a matter of taste. But to me the aforementioned means there would need to be some massive benefit of Guix over nix to make it worth considering in a professional setting. Is there, in your opinion?


There are quite a few HPC clusters that are powered by Guix:

https://hpc.guix.info/about/

Whether or not these institutions qualify as Real Companies is up to you. Other than that I occasionally see focused patches and bug reports from people using their work credentials, but nothing on the scale of Pinterest and Target of course.

We did recently get a bugfix for 'guix system container' from Google, but I suspect that was more the result of an evaluation than anything else:

https://issues.guix.gnu.org/43540

As for benefits in a professional setting, there are a few design (and implementation) differences that I think gives Guix an edge. One is grafts: Guix can deliver security updates for core packages really fast, whereas Nix needs to rebuild every dependent package. The grafting mechanism can also be used to perform other transformations, e.g. to locally enable CPU optimizations for low-level libraries without having to rebuild the world.

On the topic of security, Guix has a strong focus on bootstrapping, meaning that e.g. the Rust and Java compilers are built purely from source code, whereas Nixpkgs use opaque binaries provided by upstream projects. This property (as well as excellent cross-compilation support) is why Bitcoin chose Guix to build their installers:

https://bitcoinmagazine.com/articles/guix-makes-bitcoin-core...

Another important design difference is gratuitous use of so-called "search paths". I noticed one common criticism in this thread is that packages often needs patching to work in NixOS. In Guix, such cases are very rare. Take a look at the patches carried by Guix, conveniently stored in a single directory:

https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages...

By and large, these are just security- or bug (often test suite) fixes. I won't go into detail on how search paths work, but if you try Guix on any distro (maybe except Guix System) you'll quickly understand.

It's funny that you mention "non-machine editable Scheme code". In the Lisp world, code is data, which powers among other things the "updaters" in Guix: 'guix refresh -u foo' will update the "version" and "sha256" fields of "foo" in your git checkout.

Finally, a huge selling point for me personally, is general scriptability. I recently added code to build Chromium extensions with Guix. It was about 150 lines of code, and packaging extensions is pretty much like packaging anything else:

https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/build/ch...

https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages...

There are many other things of less importance that makes me stick to Guix, such as running the test suites of most packages, largely preventing compatibility and other run-time problems that occasionally show up in Nixpkgs (and even popular distros like Arch).

Now, the end user experience of Guix System is not great due to lack of proprietary firmware, as well as GNOME and KDE maintainers, but as a professional tool Guix is really solid in my (supremely biased) opinion.


Thanks for taking the time to write a up a detailed and informative answer!

I agree wrt desirability of grafts as an escape hatch (I think there's been some undocumented crappy version of this in nix for ages, no idea what keeps it in limbo). I also agree that bootstrapping is better in principle.

The search path (in nix?) thing, I don't fully get -- can you expand what you mean? Concerning not needing to patch upstream -- the world is full of setup.py scripts and other cruft that tries to download random stuff from the internet or write and read hardcoded system paths -- how do you deal with that?

> It's funny that you mention "non-machine editable Scheme code". In the Lisp world, code is data

One of the ego-salving lies lispers like to tell themselves ;) If it were so they'd enjoy world class refactoring, whereas in reality they can't even auto-indent code without manually futzing around with symbol properties in emacs. I haven't fully traced how guix update works, but looking at edit-expression it doesn't look very code-is-data to me (the replacement function operates at character not ast/sexp level; read is only called for side-effect as a hack twice).


With regards to needing patches, the comments in this thread suggested many packages needed patching to work on NixOS at run-time, but I have probably misunderstood.

At build time obviously Guix has all the same problems with packages that attempts network access (to download test data or whatever). I found it easier/more intuitive to provide such additional resources with Guix, but then it's been four years since I used Nix!

On the topic of search paths, IIRC Nix uses a combination of wrappers and "setup hooks" to configure things like C_INCLUDE_PATH or PYTHONPATH. In Guix, such search paths are "first class" and gets automatically configured when the relevant packages are installed to a profile.

That means no hook or wrapper is necessary, and it works with arbitrary profiles as well as "guix pack", etc -- and it is also possible to compose profiles (an emerging pattern among Guix users is to have different profiles for different uses -- a step towards privilege separation).

You'll find almost no hard coded references to "~/.guix-profile" or "/run/current-system" in Guix.

Wrt the updater code, apparently you have studied it more than I have! I think my point still stands though -- that approach would not work if not for the fact that sexps are well-structured.


Ah, OK, you mean stuff like this, right? https://github.com/NixOS/nixpkgs/pull/85103

I haven't often run into wrapper issues, but when you do it's a pain. So thanks for the pointer, I should probably look at how guix does it.


Indeed that approach looks very similar.

In Guix search paths are properties of the packages that consume them: for the GStreamer example in that PR all the plugins provide the search path attribute, whereas in Guix it is only set once, on the 'gstreamer' package.

The Guix approach has a limitation though, in that users must manually install gstreamer for the plugins to become visible in the profile. It's one of the oldest high-severity bugs in Guix: https://issues.guix.gnu.org/22138


Sure.

I was just talking from my perspective. And I found Guile much easier than Nix.

The complexity difference of NixOS compared to, let's say, Arch felt like Git to Subversion. It makes totally sense to me that a fundamentally different model of package management would require some rethinking, but it didn't make sense to me to create such a strange language for it (like Guix has proven).


I think if you're setting up a personal machine, your reasoning completely applies and a fairly superficial difference, like scheme being a more familiar language can indeed make a big difference. But I think NixOS or Guix-SD vs Ubuntu or Arch as your daily driver is mostly window dressing, you will not unlock significant productivity benefits by this choice alone unless you leverage it for setting up e.g. a unified dev/ci/prod setup with reproducible builds. At least streamlining artefact creation is where the real productivity benefits tend to come from in my experience.

However, from my own production experience with nix I find that language related overheads and frictions are just completely in the noise compared to grokking e.g. the many different flavors of overriding stuff or working out good workflows for pinning and bumping nixpkgs and individual dependencies, providing suitable overlays and integrating native language tooling (poetry, yarn, cargo etc.) with nix etc. etc. Now the language itself does have some psychological effect on wider adoption, but effectively scheme is equally obscure to almost any target audience and, IMO, an inferior design for this problem space, that presents a larger rather than smaller hurdle for most people. I guess the debugging experience at least must be better?

Don't get me wrong, I'd prefer 99% of shitty DSLs (cmake, make, pom, jinja, moustache, chef and so on and so forth) had just used even a mediocre internal lisp/scheme DSL. However, I'd say Nix is a bit of an outlier: it's IMO a remarkably elegant design that really pulls its own weight. Most of my complaints (poor debugging experience and error messages) are quality of implemenation rather than language design as such – I am not quite sure to what extent this applies to lack of static typing.

In any case one of the main usability defects of nix is shared by guix: 90% of cases should be declarative toml or similar, not some weirdo turing complete language. It's great to have a powerful language for the bits that actually need it, but a lot off stuff really shouldn't. In particular mixing metadata (description, hashes, version numbers, urls etc.) with build descriptions is just a dumb and painful way to do things and completely screws up tooling. There are tools to help with that (e.g. niv), but this should just be fixed at the source.


The language doesn't matter. It is actually very simple and nice (I read the manual, did the tutorial).

You still have to learn all the thousands of obscure schemas each thing expects and supports.

Could be written in JavaScript and you would still not know what is going on and would have to waste months in documentation and support forums.

Or maybe the documentation is just very incomplete, I don't know.


I am pretty sure moving from a DSL based on Haskell to Guile isn't a "step up" for most people.


Nix is fantastic!

I’ve started using it with nix-darwin on macOS and replacing various dot files tools and loosely coupled files and installed dependencies using Homebrew with clear and declarative Nix scripts has really changed how I manage my development environment.

I even went as far as coding up colour scheme configurations to synchronise colours between Kitty, Tmux, and Neovim, and added some configs to compile Neovim from source to get to some of its newer features, and I don’t think I would’ve done any of that (or rather, kept any of that around) without Nix.


macOS + Nix user here. How is the experience of using nix-darwin? I haven't used it yet for fear of breakage (unlike in NixOS). I still have Homebrew but only for Casks, do you know if this too can be Nixified?

> I even went as far as coding up colour scheme configurations to synchronise colours between Kitty, Tmux, and Neovim, and added some configs to compile Neovim from source to get to some of its newer features, and I don’t think I would’ve done any of that (or rather, kept any of that around) without Nix.

This sounds interesting! Are your dotfiles public?


I haven’t really played around with installing browsers, etc via Nix on nix-darwin yet. The experience is really good for the most part! Setting it up initially is a little confusing since the installation has to create a volume for /nix, apart from that it’s really smooth.

I choose to replace Nix channels with in-code tarballs of the nixpkgs repository. Sometimes that does confuse darwin-rebuild but it could also be because I’ve set it up slightly incorrectly.

My Nix files are indeed open source! There’s a colour utility and a file that uses them to create theming files. https://github.com/kitten/nix-system/blob/master/config/colo...


You can configure NPM to install "global" packages to your user directory, and similarly PIP has `--user`.

Usually, the nuclear option to installing something on NixOS that just isn't playing along (e.g. Steam and its games) is to use buildFHSUserEnv[0] which sandboxes the directory structure you're used to on other Linux systems. Of course, this means you'll be writing a bit of Nix code – if you're lucky, steam-run[1] makes software run instead, and you could probably hackily add missing libraries[2] otherwise needed, to steam-run (just remember that this is a nuclear option and not recommended because you're moving away from NixOS purity, but it does exist).

Also, I suggest posting this to the NixOS links section[3] if you want more Nix users' eyes on this.

[0]: https://nixos.org/manual/nixpkgs/stable/#sec-fhs-environment...

[1]: https://nixos.wiki/wiki/Steam#steam-run

[2]: https://nixos.wiki/wiki/Steam#Adding_missing_dependencies

[3]: https://discourse.nixos.org/c/links/12


I'll look into all of this! Thanks for the links!


If you use Arch Linux, you can get some of the advantages of NixOS using aconfmgr. It maintains the property that if something is not in the configuration file, it's not on the system; but, it builds upon that in that it still allows you to mutate the system (using e.g. a package manager) and later transcribe those edits to the configuration (or revert them).

https://github.com/CyberShadow/aconfmgr


There are lots of things to be said about Nix and NixOS, and many of these things have been mentionned in this page, but there's one thing I really like with Nix : the fact the the configuration is expressed as a function that takes its own result as argument, and that the final configuration is the fixed point of that function. This is a very powerful concept, as these functions can be composed together.

I think this idea is not specific to Nix, and I wish it was used a lot more in configuration languages. For example, it was something I really missed when using Ansible. The lack of this feature means that writing the inventory is much harder than it needs to be, and I've seen horrible hacks that try to get around this.


I tried NixOS out for a while on my laptop. I loved the idea of an immutable system with all the config in one place. The implementation, though, was really a terrible user experience. I got past the weird config language, made a few contributions to Nixpkgs to get the packages I wanted, etc. The deal-breaker for me was the inability to run third-party binaries due to the departure from standard directory structure. After all the frustrations with NixOS, I was motivated to go to the opposite extreme so I could stop spending time maintaining my system and focus instead on the tasks that I wanted to use my system for. I've been [mostly] happily running Ubuntu LTS releases ever since.


> The deal-breaker for me was the inability to run third-party binaries due to the departure from standard directory structure.

Did you know know we have FHS compat environments: buildFHSUserEnv?

This is our fallback solution for huge closed-source things like steam + its game games that we agree it doesn't make sense to repackage individually with patchelf.

I'm saying we agree and if we didn't have `buildFHSUserEnv` it would be a dealbreaker for many more than you. Please give it a shot, and us a second chance!


The pain I run into is that I very frequently need to use buildFHSUserEnv and it's just cumbersome enough that it's almost easier to not use Nix at all. It would be nice if there was a way to make this "just work". steam-run feels very hacky and I am loathe to use it in production, though I admit I've used it a lot.

Rewriting the library paths for a given binary also works but is cumbersome.

Ideally there would be a few extra tools in Nix to say "adopt this binary" in a similar way we can install things into our environment permanently, and to transform a binary to look for dependencies in the right places.


Neat. How long has that been around? I tried NixOS in mid-2016. I don't recall what package I was trying to use at the time (likely PlatformIO/Arduino or Rust ecosystems), but the only advice I remember finding was to run some utility to rewrite the paths embedded in the binary.


If you're interested in just the package manager Nix check out https://nix.dev/ It guides you to get a reproducible development environment up and running with nix. This way you can get all the goodies like `nix-shell -p nodejs` without switching your OS first :)


Seems interesting, thanks for the link!


Any users of Guix here, and what is your experience?

From what I understand it’s inspired by NixOS, but instead of the DSL for configuring packages Guix uses Guile.


Guix is very nice, but suffers a bit from:

- Having less development effort than Nix involved in packaging; some packages end up broken/out of date as a result

- Its more "pure" packaging ethos (no bundled dependencies, all dependencies must themselves be packages for Guix, etc). I like this in theory but practically it makes packaging some applications (Go/Node ones especially) effectively impossible. Debian seems to have the same issue: https://lwn.net/SubscriberLink/835599/b4de94c924ae4463/

- The build farm often doesn't have substitutes available for certain packages, which tend to be precisely the ones that take ages to build on older hardware. Cue multi-hour IceCat builds

- There's not much documentation available on packaging beyond the trivial cases. Packaging many applications is pretty simple, but for the ones that aren't it's a bit of a guessing game and trying to read through definitions of other involved packages

All that aside... these are complaints that I have as a dedicated Guix user, and I've thoroughly enjoyed my time using Guix System. It's the first distro I've ever used that I haven't felt has gotten "polluted" after over a year of tinkering with it - I've installed (and uninstalled) multiple DEs, and I know I can trust the package manager to actually remove every single thing that was installed as part of that.

And it's really nice to use a distro whose entire configuration system and package definitions are written in a single language (Guile) - I've written a few simple package definitions myself and I think the fact that it's all written in the same language has made it easier to dive deeper into how the system works after having written a few packages.


I've been running guix on my systems for about two years now. I can comment.

Generally I love guix. As a tool its very ergonomic to use, the documentation is excellent, and the mailing lists are active and informative. As for specifics:

* The CLI is way better than nix's and each command is fully documented and flags are intuitive. `guix install foo` is a lot more intuitive than `nix-env -iA foo`. Nix is in the middle of overhauling its CLI but until that task is complete I personally believe there's no contest.

* Guix has a lot more first party functionality when it comes to importing packages for some languages. If someone's project is in python, ruby, haskell, or ocaml it only takes `guix import fooRepo package` to create a package that isn't yet in guix's package repository. Also this functionality is easily discoverable thanks to guix's excellent documentation. I wish this extended to nodejs projects but that's likely never going to happen.

* There are a number of built-in ways to share guix packages with people who aren't using guix with the command `guix pack`. This has come in handy for me in a number of situations like creating singularity containers for coworkers or trying out stuff they're working on in an isolated environment.

* Speaking of containers, `guix environment` lets me run software in ad-hoc containers.

Now, all of this is great but the desktop experience still leaves much to be desired. The desktop experience has all of the problems running NixOS has except the added trouble of Guix's immaturity. Gnome is only 3.34 while most distros have already migrated to 3.38. Guix has been a pain to run on my laptop, so much so that I've resigned to only use it as a package manager and DevOps tool.


It's also free software, which is a pro for some and a con for others.


Hold on there, let's not blur any definitions - Nix is also Free software, with the tools chiefly licensed as LGPL.

The difference comes in the maintained software distribution, nixpkgs, being less strict in its package inclusion criteria than its guix equivalent.


Sorry, yes. That's what I wanted to say.


I tried NixOS in a VM a while back and I found it pretty confusing. I liked the idea of having a configuration file that describes the packages installed in the system. The first thing I did was use the CLI to install Firefox, then I found that it didn't update my nix config, nor did there seem to be a CLI command to say "install this and add it to my config".

Instead, it seemed that I had to manually update the nix config. Then, I had to learn the syntax of the language. Then when I figured out the basic, I added Firefox, but it required me to add some parameters (I don't remember the specifics) but I couldn't find any explanation about what those should be for the Firefox package.

I don't understand why they don't have tooling (or didn't at the time) to update your nix config for you.

If they want to convert people over to their way of doing things they have to lower the barriers to entry substantially.


There is a global config and a user-specific one. So every user can install (without root) their set of packages and their PATH will be changed accordingly.

You probably tried to add firefox to your local one - which should be good enough. I wouldn’t really want a program to auto-update the global configurarion.nix


I really recommend people try Nix first without the full blown OS if they are hesitant.

I find for my laptop I get 90% utility that way in including user systemd services.

I love all the NixOS blog posts but I hate that they are always so surface level. NixOS feedback or writeups never go beyond this shallow level.


I didn't went into details since I'm relatively new to Nix.

I'll make a follow-up in more time (some months) and go in more details!


Not a comment on your post but the NixOS ecosystem in general

Probably should've used the word "dislike" instead of hate. Apologize.

As someone whose been using Nix for almost a year (not NixOS as long) I struggle that there is zero advanced write ups.

Could be because it's the same experience which is good news.

But there's a series of advanced concepts that deserve more love: custom Nix cache, distributed building, remote deployments , NixOps, writing eloquent derivations, secret management (please!), how to sanely use vim_configurable etc...

I spent a long time documenting the Maven (Java) documentation and recently had it approved.


I have a suspicion that Nix will be my secret sauce for cross-platform Haskell gamedev. There's obviously a lot of work to do, but my plan is to solve problems instead of complain so I have a good feeling about reaching that mountaintop in the long-term (3-5 years.)


I installed Guix the other day as a potential new server installation. What attracted me initially was being able to declare the services available, like Ansible. Nix is a non-starter for me as an emacs user. You will never regret using a system based on a fully-fledged, general-purpose programming language like scheme as opposed to a domain-specific one.

So far I think it's brilliant. I didn't even know about the functional aspect but once I "got it" it makes me not wish to go back to a mutable system. I say this is a long time gentoo user. It won't replace my gentoo system any time soon, but it certainly has potential.


This is a good overview of NixOS however it's very limited and barely scratches the surface of what Nix can do. I consider it a complete replacement for the "reproducible environment" problem that some programming languages solve (e.g. Python's virtualenv, Haskell's cabal repl), among others.

A simple example of this is when I want to run a Python script from the internet, I can execute

  nix-shell --run "python3 foo.py" -p "python3.withPackages (ps: with ps; [ numpy ])"
and now I'm in a shell where numpy is avaliable to the Python 3 interpreter. Or I could test the Haskell QuickCheck library and run

  nix-shell --run "ghci" -p "haskellPackages.ghcWithPackages (ps: with ps; [ QuickCheck ])" 
See[0] for a way to run programs without even installing them by prefixing them with a comma, e.g. `, hello`. Or what about running any Linux ELF binary by automatically getting their shared dependencies at runtime[1]? Or generating bootable ISOs from your NixOS configuration[2], cross-compiling with little effort[3], and so on.

These problems have already been solved to varying degrees in other places, but Nix lets you unify them (think of the huge amounts of libraries downloaded by cargo, cabal, node and so on scattered amongst projects and your home folder, Nix stores everything in /nix/store/) into a single framework.

I'd like to also say that the Nixpkgs repository[4] is super easy to contribute to, just open a PR on GitHub as opposed to sending patches via mailing lists, which is checked via the CI. I'm not sure if there's something analogous on other package repositories but there's also a bot[5] that opens thousands of PRs updating and testing packages automatically.

[0] https://github.com/Shopify/comma

[1] https://github.com/Lassulus/nix-autobahn

[2] https://github.com/nix-community/nixos-generators

[3] https://matthewbauer.us/blog/beginners-guide-to-cross.html

[4] https://github.com/NixOS/nixpkgs/

[5] https://github.com/r-ryantm


Another way you can use nix-shell: with Nix, shell scripts can declare their dependencies. For a random example, I have a script that extracts chapter information from a DVD. Its shebang looks like this:

    #!/usr/bin/env nix-shell
    #!nix-shell -i /bin/sh -p ffmpeg_4 lsdvd python3
This is the equivalent of "#!/bin/sh", but with some package dependencies. Without nix, this script would implicitly require lsdvd to be available, increasing the complexity and fragility of system administration: if you scp the script to a different machine, the script is broken there until you install lsdvd. Even on one machine, you have to keep lsdvd installed (and remember what you have it for). Nix takes care of all that: when you run the nix-empowered script, it will make sure lsdvd is available in the script's environment. I keep an extremely minimal set of packages install system-wide (and nothing installed to my user environment), and declare dependencies in the places they're actually needed. I no longer think in terms of installed-or-not; everything is available.


Seems really useful, thanks for the links!


Do you do these sort of things often in production?


No, this is to illustrate that despite Nix being purely functional it doesn't necessarily mean you lose velocity when doing things interactively. In production I usually use Docker. Nix can generate Docker images though, so I'd like to try it out sometime.


Has anyone used GUIX and can give a comparison? I think they are similar ideas but GUIX standardised on Scheme. https://guix.gnu.org/


My problem with nix is that it uses way too much memory when building. It's simply impossible to install certain packages if you don't have a lot of memory to work with.


I'm working on Nix tutorials at https://nix.dev - let me know what's missing :)


Still didn't get to chose between nix and silverlight


I think you mean Team Silverblue, right?

They are very different, but lead to some of the same benefits. Silverblue largely follows the same system layout as traditional distributions (FHS, with packages in a global namespace). But compared to traditional distributions, it replaces the package manager with snapshots in a git-like store (OSTree). The system is immutable and provides atomic updates/rollbacks, like NixOS. They offer an mechanism on top of OSTree (rpm-ostree) to layer traditional RPMs from Yum/DNF repositories. To keep the base system lean and immutable, they encourage installing desktop applications through Flatpak and doing development through traditional, mutable containers through podman/toolbox.

Silverblue is a bit strange in that it is in two worlds: on the one hand it touts the benefits of immutable systems, on the other hand it acknowledges that in their own setup, development is only really comfortable by also providing mutable systems through containers.

NixOS is far less compromising than Silverblue. It chooses one model, functional package management, and that's the way of the highway (no FHS, immutable store, all packages live in their own directories in /nix/store). There are some small escape hatches like buildFHSUserEnv, but no major compromise as Silverblue has. Nix shares some benefits like atomic updates/rollbacks and an immutable system. But provides many others that Silverblue's model cannot easily provide (or has as the answer 'spin up another container'), such as permitting several different versions of packages in parallel, virtual environments (but for any package), etc.

I think both approaches are very promising and not one is necessarily better than the other. Nix/NixOS' approach is more consistent and more powerful. However, Silverblue's pragmatic use and strong integration of containers, makes it much more familiar for most people. Also, much more software works out-of-the-box as a result.


Honestly, I have to say I'm in two minds about NixOS.

Conceptually its a great idea, but I'm a bit worried about the possibility of all-mighty failures caused by adding the extra layer of abstraction and complexity. Its a bit like messing around with the buzz-word-of-the-day Kubernetes compared to just getting the job done with a good old fashioned VM.

Given solutions like Salt are around that can manage reproducible builds anyway (in conjunction with PXE installs), I see limited applications for NixOS.

Also, sometimes its nice to have the warm fuzzy feeling of using a software vendor's supported package build on a supported OS (e.g I'd rather run a package from the official Postgres repo then mess around getting Postgres working on NixOS).


I'm running NixOS in a VM, trying to evaluate if it's worth switching from Arch to NixOS before making the leap.

> possibility of all-mighty failures caused by adding the extra layer of abstraction and complexity

In the end, I think all distributions ends up with similar layers of abstractions and complexity, mostly regarding packaging, but sometimes also other components.

What I've found when using NixOS compared to Arch, is that if I screw up my Arch installation I either need to sacrifice my time to try to fix the screw up (which sometimes adds spending time just learning/reading about some concept I don't know about) or I need to recover from backups, so I can get back to work.

With NixOS screw ups, I simply choose the previous version on boot and I'm "recovered". Leads to me getting back to what I was doing faster, but missing the opportunity to learn my own personal stack better. But not every moment needs to be "understand everything 100%", which in Arch-land, tends to happen, otherwise you continue to screw up.

Although I'm still on the fence of upgrading to NixOS because the OS as an concept + it's own language is still not easy to learn, especially for more advanced usage, it's getting closer each day to just dump Arch and start using NixOS full time. Mostly because the reproducible nature of the OS.


I too was using Arch before and a friend convinced me to do the leap and I don't really regret it.

One of the advantages is that packages just works on the contrary of the AUR where I had lots of problems for lots of packages that wouldn't just not build or work.


how do you break Arch so bad these days?

last major issue I had was when everything moved from /bin to /usr/bin.


Keep trying out new things, new things don't work as I want so I wanna go back to how things were and have to manually "rollback" stuff (see deleting files, changing configs). Also managed to screw up the bootloader and partitions on more than one time. I'm not gonna pretend I'm an expert, I just want a simple system, which Arch really is. But sometimes too simple, requires a lot of reading and understanding, which is usually not a problem, but sometimes it is.

One recent example was me trying out KDE Plasma. Usually I use AwesomeVM but the HN thread about the new Plasma version made me try it out in Arch. After the install and trying to use it for a while, I wanted to go back.

Uninstalling the package(s) is not enough, as it already has been overwriting bunch of stuff and changed configs that are not being rolled back after uninstalling.

Still to this day KRunner launches (via some d-bus command or something like that) when I do my Super+R shortcut, which usually runs the AwesomeVM launcher, not KRunner. Haven't figured out how to get rid of it yet, but got other stuff to do right now, so simply living with it for now.

With NixOS, I'd just reboot and select the previous version where KDE Plasma was never installed.


I feel like the problems you're citing (inability to simply roll back, etc.) aren't really Arch problems specifically—you'd have them in any traditional distro (like Debian) too, right?


Oh yes, absolutely, I'd surely screw up equally often if I was using Debian, Ubuntu, Fedora or any other distribution, if not more. I was just comparing Arch to NixOS as Arch is my daily driver, while I'm evaluating the switch to NixOS.


I even "DE hopped" using NixOS, trying out 3+ different DEs for fun, and once I was done I just had to revert to an older generation, no nasty leftovers.


I use NixOS unstable on my desktop/work machine, but when I just started using NixOS, I even regularly hopped between the latest stable release and unstable.

Another fun related feature: NixOS really only requires /nix and /boot to boot. So, some of us just nuke everything except /nix, /boot, and /home on boot:

https://grahamc.com/blog/erase-your-darlings


The issue wasn't the system broke, in fact, my system was doing pretty much alright.

The problem was: in the AUR, lots of packages didn't built or launch, and even in the official repos, some packages were missing libraries or just not having the right versions.

I was tired of tinkering to get everything to work as I wanted.


The problem was: in the AUR, lots of packages didn't built or launch,

I used Arch for a while before NixOS. Another problem I encountered with the AUR is that, since the AUR is not built as a single consistent system with Arch itself, often packages from AUR would start failing because some library was upgraded in Arch and the newer version was ABI-incompatible with the version that the AUR package was compiled with.


Out of curiosity what do you think of how Arch and NixOS compare to Debian or Ubuntu? (I'm asking to help me calibrate against what you're saying since I've used all of these except NixOS.)


Imho, Arch is a similar style to Debian/Ubuntu but different package manager and slightly different semantics in a few places. NixOS is radically different and if you can make it work for you, you’ll likely be much happier after the learning curve. If however your needs are just outside the norms enough, NixOS could also just as well be very frustrating. It’s one of those things you’ve gotta try and invest a reasonable amount of time in, which might not pay off, but if it does, could pay off big (or so the marketing pitch goes).


Thanks!


Something I don't really understand coming from arch, how am I supposed to handle the system installation?

Why is partitioning not part of a config file, but done at installation?


I have used NixOS only for a year so I'm no expert but I try to answer.

The config file has this line:

  imports = [ ./hardware-configuration.nix ];
This file hardware-configuration.nix is typically generated semi-automatically during the installation. It has stuff like

  fileSystems."/" =
  { device = "/dev/disk/by-uuid/14b5b22f-6cd2-4da5-a9a5-6ee74b76509d";
    fsType = "ext4";
  };

  fileSystems."/boot" =
  { device = "/dev/disk/by-uuid/7D69-81E5";
    fsType = "vfat";
  };
AFAIK you can include these details in configuration.nix if you happen to know them. But most of the time these are so hardware-specific details that you don't want to write them manually. Does it make sense?


That's an accurate description. I just want to add some info how the install process ifself works so people get a better picture of it.

For the initial installation you actually have to set up the partitions and mounts inside the root filesystem manually similar to what you have to do to install Arch.

Then you run the install command. The install command sets up the system with a default (or customized) configuration and also generates the hardware-configuration.nix file so that it matches the root filesystem you have set up before running the install command.


There is something called nixpart: https://github.com/NixOS/nixpart but it's very immature as per as https://github.com/NixOS/nixpkgs/pull/21403

All help is welcomed :).


My understanding of it that you really want to have two different configurations, one that is system/hardware specific and one that is "user" specific. So let's say I have a desktop + laptop I want to run NixOS with, I'd want the hardware config to be different on them, but with the same user-land config. Hence the installation config is usually automatically setup at installation time, and then the user config is put in place.


This is about right but let me clarify a bit.

The configuration.nix system configuration can be moved between systems, but imports a generated hardware-configuration.nix that really should not be moved between systems.

If you don't want user and system specific configuration to intermix by having user-specific software in your system configuration and you want to manage you the dotfiles in your home directory in the style of Nix there is another popular project called home-manager which enables that, but that's totally optional.


> Given solutions like Salt are around that can manage reproducible builds anyway (in conjunction with PXE installs), I see limited applications for NixOS.

Having used NixOS for more than a week, I have the same but opposite feeling. If you don't mind the hyperbole, NixOS is a solution, Salt and similar as a substitute is duct tape. :)


Salt/Chef/Puppet/Ansible/etc are generally “good enough” tools and work for many needs, but over time cruft will inevitably happen (unless you frequently start from a clean base image). NixOS tries to avoid that by making it difficult to accidentally do a one-off outside your tooling and/or install things that unintentionally (or intentionally) stomp on other installed things in your system.


I used to manage the development environments of several hundred developers using Chef. It kind of worked, but would not very well support configuring files in the users home directory for example. Also setting up services locally needed for development (RabbitMQ, Tomcat etc) became much easier with Docker. I switched to Docker for that purpose, and most of the chef scripts became unnecessary. What the nixos package manager can easily solve is managing configuration files in the users-home (using home-manager), as well as installing different versions of different tools at the same time. You can even go as far as using direnv to automatically provide the tools (jdk, nodejs, gradle etc) when entering a given project just checked out from git.

Therefore Chef (they other tools are equivalent in my view) is IMHO not a good enough tool to manage dev environments.


> Therefore Chef (they other tools are equivalent in my view) is IMHO not a good enough tool to manage dev environments.

I agree, but your and my definition of “good enough” is not the same as everyone else’s. These tools wouldn’t be as heavily used if folks didn’t feel they solved a problem they had.


They used to solve some problems in a way that was good enough at that time. Nowadays setting up services, where you have to take care of avoiding port conflicts, is much easier with container technology. Modifying config files in the users directory is in my experience a pain because chef was not designed to do that. You have to do all kind of workarounds to get permissions right. Just using Chef for abstracting from which package manager you use also does not fully work because package names can be different between Linux flavors. Chef also requires a ruby installation, which itself is a problematic large dependency which might conflict with another ruby version on the system.

Update: trying to install the same package in different versions at the same time is also a pain.


Having worked with these tools, in comparison Salt/Chef/Puppet/Ansible are a collection of footcannons wrapped in the guise of a solution. The entire idea of trying to manage a fleet of stateful OS installations and stay on top of it all once it gains the slightest hint of complexity is a fallacy.


> failures caused by adding the extra layer of abstraction and complexity

I perceive nix as a tool that removes a layer of abstraction and complexity - the FHS. Having an app working is easy. Having multiple apps share the same FHS is complex because of conflicting requirements. Without FHS, there is no shared dependency resource thus no conflicts. Multiple applications are just as easy as a single application.


Yup!

I see NixOS as an easy way to re-install easily my system when I get a new machine or just to sync easily packages between my laptop and desktop (so they almost have the same things installed on them).

As for servers, I don't really see the point of nix as usually, pre-made and preinstalled images are already deployed. I think I'll still stick with Debian and all the usual software such as Docker for this usage.


It's a shame to me how docker has come to be seen as "the usual software", as it's really just another layer of duck tape which uses OS features to pretend that arbitrary build processes are "reproducible" (when actually the way most Dockerfiles are written, they are most certainly not).

As a result, working with docker images often needs special privileges which leads to complex situations involving docker-in-docker etc., which just shouldn't be necessary.


Docker’s build process sucks, but that’s not the point of Docker—the point is that it’s a standard image format for containers which allows for orchestrators like Kubernetes to exist without caring about the internal details of any given container (e.g., what language it uses). It does pretty well in that regard, and you can even use Nix to build Docker images. Nix’s value proposition is reproducible builds, and while it does reproducibly build software, writing those definitions is incredibly hard (though the difficulty varies widely from package to package).


No, I absolutely acknowledge the value of a "docker image" as, essentially, an interchange format.

But it's also reached for as a solution for a whole heap of other things which are much better done in other ways.


Unfortunately today there aren’t many better options. Building images with Nix is great in theory (as Nix in general is great in theory), but it implies packaging one’s own app with Nix which is an enormous burden in most cases. There are other projects emerging that give us better image build systems than Docker, but none are well-tested at this point such that their tradeoffs are understood. This is a real pain point in the ecosystem, and it will be interesting to see how it resolves.


> packaging one’s own app with Nix which is an enormous burden in most cases

I have not found this at all tbh.


I’ve tried this personally, and we attempted it as a team professionally and in both cases the juice was deemed not worth the squeeze. In particular, we were constantly packaging low-level transitive dependencies for C projects, and ultimately you had to not only know how to build your own package, but also any package for your entire dependency tree. If your dependency tree doesn’t involve any C dependencies (or if Nix definitions already exist for them) then you probably won’t run into so many issues (which is likely to be the case for Go, Haskell, etc—languages that don’t have a heavy emphasis on C dependencies and probably those that can be statically linked) but for Python, Node, etc you will probably have problems. None of this is to speak about the dearth of documentation or the difficulty using nixpkgs as a reference.


I tend to find unmet dependencies to be an opportunity to package that dependency and upstream it. Even keeping the package private in situations where that's not appropriate feels like less work than the alternative of manual management.

And I've actually found the discoverability of the tricks used in nixpkgs to be pretty amazing. Sure the manual could always do with being more thorough (indeed it's always getting better), but again, in comparison, the quantity of stuff understandable from just reading the contents of nixpkgs and knowing basically one language is huge.

I compare it to a lot of the other systems I work with where just to decipher relatively simple setups people have created I have to understand cryptic combinations of terraform, Dockerfiles, bash, helm, github workflows, concourse pipelines, puppet/chef/ansible/..., travis.yml, Brewfiles... each of which being weirdly arbitrarily restricted and inevitably needing to call in yet another tool to fill in the gaps in their capabilities.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: