I have to say that that "surprisingly simple" thing is happening more and more for me on NixOS as well.
Recently a customer wanted me to use Fedora (I never visited the RPM side of the world before), and after truly the worst installer I've ever used, the actually system was nice. I do like Cockpit.
But then I needed to install an initrd that would me unlock the full disk encryption via SSH (it's a remote headless box). It took me half a day and a forum post to get it to work. I wrote a full page of notes for next time. Then the Firewall: I hit a bug (plus user error) which left me wrestling with a non-existent Tailscale interface for a while (it warns you for non-existing interfaces, but not with only a case mismatch, it then lets you do everything as if the interface exists), but after some hours I was done setting the zones, another page of notes and commands to enter to get to the desired state.
These configurations are both 1 or 2 lines in a NixOS config file. And that "work" is now done for all my NixOS servers.
You could argue that NixOS hides a lot of complexity, but so do Dracut and Firewalld of course. Nix is difficult, it's a high level abstraction. But it also just a bunch of key-values, and write-once, deploy everywhere.
>> You could argue that NixOS hides a lot of complexity
They both have the same complexity in that scenario. Underneath it's very comparable configuration for both but Nixos provides an easy abstraction for that specific case.
If you can stay on the happy path with nixos then it's pretty lovely. I've even adopted nix-darwin for my mac's too.
I'd still deploy Redhat/Fedora over nixos on anything revenue generating though. The problem is when you have to come off the happy path in nixos and now you're debugging some interestingly written c++ code that evaluates a language that has a derivation expressing what you wanted done. Contrast with the redhat situation, it's simpler but less convenient in the general case.
> The problem is when you have to come off the happy path in nixos and now you're debugging some interestingly written c++ code that evaluates a language that has a derivation expressing what you wanted done.
I agree that Nix or NixOS are risky tools.
But it's not a problem that the `nix` program is written in C++.
A lot of the friction comes from the tension between NixOS's idiosyncratic design & its constraints, against the often 'dirty' way software is practically written.
For example, roughly, Nix's ideal software follows `./configure && make && make install`, where nix can then symlink the dependencies & maintain these in a read-only store. -- Whereas, say, Python wheels break this (because the precompiled binaries assume shared libraries are available globally).
When you run into friction with NixOS, you may need to understand things with a depth and breadth which aren't required with more common Linux distributions. (Including e.g. maybe needing to understand the rather large and obscure nixpkgs).
The difference is, you can create proper abstraction modules that put everything together, from dependencies, to config files, firewall rules etc and have nice options for your abstraction.
No other system provides this in that sane way. I used countless configuration systems, from custom bash hacks, ansible, chef, puppet, salt - I have seen a lot.
> The difference is, you can create proper abstraction modules that put everything together, from dependencies, to config files, firewall rules etc and have nice options for your abstraction.
Yes, this is an understated benefit.
The declarative interface is nice.
That NixOS configs are modular allows you to create those abstractions. -- In the same sense terraform modules are "infrastructure as code", NixOS modules are "system configuration as code".
Yeah once you've used Nix[OS] and home-manager, it's hard to go back to apt or brew or the dreaded "sudo make install" without feeling like you need to have a shower afterwards. And I was a loyal Ubuntu person for like 15 years. It's especially true if you're a dev installing and uninstalling all day long.
With homebrew, you can have Brewfile that can serve as declarative source of truth.
I try to install all software via homebrew, mise (https://mise.jdx.dev/), and scoop (https://scoop.sh/), and setting up a new machine now takes me minutes. Meanwhile I don't need to deal with Nix language.
This has been my experience as well. Before I switched to NixOS I used ubuntu for 2 years. I never grokked the ways of apt and how or why it would "randomly" brick my system in some way. With NixOS this has never happened. `nix-shell` is dead simple, adding packages to environment is dead simple, never has it bricked my system. The hard part of NixOS is if you want to do advanced things with the actual nix language, and of course the horrible error messages.
In terms of all the linux systems I have used, NixOS seemed to least magical to me in terms of what is happening under the hood.
What?! Insane take. NixOS is where the most "magic" happens, over and under the hood. It brings it's own language!
Simple package based distros like Arch basically just extract archives. Very few packages trigger post-install steps which usually just (re)generate something like initrd.
Afaik, bricking Ubuntu is either due to user error (e.g. mixing incompatible package sources) or the devs released broken/buggy packages...
If you're not making changes to the bootloader it's essentially impossible to brick nixos: updates are fully atomic and every change can be rolled back by booting into an old generation.
This combined with the fact that the full source code for the system is contained within a single monorepo that I can checkout and grep through makes NixOS the easiest to understand and most transparent distro I have ever used.
The nix store can do hard linking for the hashsum files. The nix store is read-only so you don't get modifications in general - does not really matter for boot disks, but in general.
Recently a customer wanted me to use Fedora (I never visited the RPM side of the world before), and after truly the worst installer I've ever used, the actually system was nice. I do like Cockpit.
But then I needed to install an initrd that would me unlock the full disk encryption via SSH (it's a remote headless box). It took me half a day and a forum post to get it to work. I wrote a full page of notes for next time. Then the Firewall: I hit a bug (plus user error) which left me wrestling with a non-existent Tailscale interface for a while (it warns you for non-existing interfaces, but not with only a case mismatch, it then lets you do everything as if the interface exists), but after some hours I was done setting the zones, another page of notes and commands to enter to get to the desired state.
These configurations are both 1 or 2 lines in a NixOS config file. And that "work" is now done for all my NixOS servers.
You could argue that NixOS hides a lot of complexity, but so do Dracut and Firewalld of course. Nix is difficult, it's a high level abstraction. But it also just a bunch of key-values, and write-once, deploy everywhere.
They both have the same complexity in that scenario. Underneath it's very comparable configuration for both but Nixos provides an easy abstraction for that specific case.
If you can stay on the happy path with nixos then it's pretty lovely. I've even adopted nix-darwin for my mac's too.
I'd still deploy Redhat/Fedora over nixos on anything revenue generating though. The problem is when you have to come off the happy path in nixos and now you're debugging some interestingly written c++ code that evaluates a language that has a derivation expressing what you wanted done. Contrast with the redhat situation, it's simpler but less convenient in the general case.
I agree that Nix or NixOS are risky tools.
But it's not a problem that the `nix` program is written in C++.
A lot of the friction comes from the tension between NixOS's idiosyncratic design & its constraints, against the often 'dirty' way software is practically written.
For example, roughly, Nix's ideal software follows `./configure && make && make install`, where nix can then symlink the dependencies & maintain these in a read-only store. -- Whereas, say, Python wheels break this (because the precompiled binaries assume shared libraries are available globally).
When you run into friction with NixOS, you may need to understand things with a depth and breadth which aren't required with more common Linux distributions. (Including e.g. maybe needing to understand the rather large and obscure nixpkgs).
No other system provides this in that sane way. I used countless configuration systems, from custom bash hacks, ansible, chef, puppet, salt - I have seen a lot.
Nix is just on another level. Never going back
Yes, this is an understated benefit.
The declarative interface is nice.
That NixOS configs are modular allows you to create those abstractions. -- In the same sense terraform modules are "infrastructure as code", NixOS modules are "system configuration as code".
I try to install all software via homebrew, mise (https://mise.jdx.dev/), and scoop (https://scoop.sh/), and setting up a new machine now takes me minutes. Meanwhile I don't need to deal with Nix language.
In terms of all the linux systems I have used, NixOS seemed to least magical to me in terms of what is happening under the hood.
Simple package based distros like Arch basically just extract archives. Very few packages trigger post-install steps which usually just (re)generate something like initrd.
Afaik, bricking Ubuntu is either due to user error (e.g. mixing incompatible package sources) or the devs released broken/buggy packages...
This combined with the fact that the full source code for the system is contained within a single monorepo that I can checkout and grep through makes NixOS the easiest to understand and most transparent distro I have ever used.
Those ternary blobs tend to be cross-platform, I hear.