> My personal administration [prior to NixOS] involved a lot of digging through installed software's FHS to figure out how things worked. [...] Mutable distros you directly edit stuff in /etc, then build your knowledge on top of that foundation.
That's true. Once you have found your footing with the Nix language and figured out some basics of how to navigate the NixOS modules in Nixpkgs, the latter becomes a rich source of examples on how to configure everything on a modern Unix-like system, from mounting a btrfs subvolume in your initrd via systemd/dracut integrations to setting up PipeWire to emulate PulseAudio. But while NixOS can still teach you a lot about how a working Unix-like system is put together and how its stack is configured, the most useful point of entry for such exploration is very different from what you might be used to on other distros.
You can also learn by exploring the Nix profiles and the Nix store of a working system, much like you would walk through the FHS on a ‘normal’ Linux system— after all, all of your system-wide config files can eventually be hunted down in the Nix store. If you run `ps` on a NixOS system, you'll see explicit references to RC files for lots of programs that are wrapped to point to specific config files, and for running persistent services. But it's probably not as useful as going directly to the Nixpkgs source, once you've learned to read a little Nix.
> A NixOS beginner shouldn't be touching config files, and can't even do things like replace a binary with a shell script wrapper to understand when and how a program is run by a different program.
That's an interesting thought. I didn't come to NixOS as a beginner in the Linux world; NixOS was not my first distro. (I think that's true for most of us in the community.) With NixOS, neither the paradigm nor the community really encourages the kind of monkey patching, that kind of learning by brute intervention on a running system. Even so, I think it would be possible (if perhaps a bit perverse) to write a textbook or a course like ‘Learning Unix with NixOS’. I think using a read-write store as a teaching tool before showing the reader how to use Nix itself to wrap programs that live in the Nix store would be fine.
> [NixOS users] need to dig through NixOS specific docs to understand how they're supposed to configure something, rather than falling back to the regular packaging docs.
Right, NixOS definitely changes the sort of ‘order of recourse’ users will want to make when configuring a piece of software. I'd say it looks something like this:
1. Is there an existing NixOS module for configuring the software I want to use?
2. If so, does the module have any high-level options that look so convenient that I should try them right away?
3. Is there any additional, special configuration that I need to do?
If the answer to (1) is no, or the answer to (3) is yes, then it's definitely necessary to consult the upstream documentation on the software you want to use. In the case that a module exists but you need special config, there will always be a way for you to pass configuration options defined upstream directly to the application through your NixOS configuration.
A NixOS fanatic might frame this
> Whereas with Debian you only need Debian documentation to know how to install a package, but after that the upstream package documentation tells you everything else.
in an alternative way:
> Whereas Debian only helps you to install the package, NixOS will also help you perform common configuration tasks. It's only when you need to perform peculiar configuration tasks for your specific needs that you really have to dive into the upstream documentation.
At the same time, knowledge of some upstream component (e.g., Xorg, connman, OpenSSH, etc.) always remains applicable with NixOS, if you want it to be. Everything that's configurable under /etc/something/or/other on Debian remains configurable on NixOS in a straightforward way, either by specifying key-value type config in the Nix language or (in the worst case) by embedding a config file snippet in your NixOS configuration.
> As an aside, I feel like NixOS asks a fundamentally different question - "how can we mitigate Linux/Unix's complexity" rather than the traditional mutable distro question of "how can we best interact with Linux/Unix's complexity".
I think this is well put, and it's what I was getting at above with the idea that thinking about the particular structure of some program's RC file is a last resort in NixOS. But it's not entirely one-sided! The NixOS module system serves not just to shield users from that complexity when they don't need to confront it, but also to teach them about it when they do. For me, that's one of the reasons that learning the Nix language and exploring the Nixpkgs codebase is so worth it.
> That being said a lot of smart people here and in my peer group swear it's the truth, despite none being able to elevator pitch it.
OK, I’ll bite.
Nix is a build system. NixOS is a Linux source distro built on top of it (cf Gentoo, gittup, BSDs). Except you won’t need to build anything.
Nix builds (should) execute in an isolated environment, thus the build artifacts are (ideally) bit-for-bit identical no matter where they were built. This means you can have a shared artifact cache (cf Bazel). Now for the clever part: in a distro, such an artifact cache is the same thing as a binary repo. Thus you are in fact using a (somewhat disk-space-hungry) binary distro until you want to patch something, at which point it transparently reverts to a source one (up to and including rebootstrapping the system compiler if you wish).
That’s the gist, but there are some more goodies on top of that.
First, none of this really requires a NixOS-only world. Thus, as an intermediate step, there’s Nixpkgs: a ports-like collection of packages that runs on conventional Linux and macOS systems (*BSD support is possible but has bitrotted). To maintain isolation in such an environment, all binaries it builds refer to dynamic libraries by build hash rather than load whatever’s present, and are usually wrapped to ensure other parts of the ambient environment don’t leak through. But once you’ve done that, more or less the only thing remaining to have a “gimme a shell with P, Q, and R in it” command is to point PATH to the right build directories. Hermetic build environments (cf virtualenv) for any supported language, user-scoped rootless package installs, good stuff.
Second, what NixOS adds on top of that (apart from a kernel) is a system for building system configurations out of Nix-language descriptions. It’s a bit clunky, like all config generators, but once you commit to maintaining all of your /etc that way a full rollback of (the NixOS-managed part of) the system is a single GRUB selection away. There are also things like “run a QEMU with this system config inside”, “build a Docker-compatible image with this system config inside”, etc.
Finally, as to how this works, Nix the build language is really simple, it’s JSON + (pure) functions + laziness + a build recipe type. Usually you just generate some shell or Perl or whatever scripts and stuff them into the recipe, so for Nixpkgs it’s honestly a bit overkill, but NixOS uses it to define a rather clever system with options that (if defined) set values of other options that ... all the way to the options that define the raw content of each file in /etc, with rules for merging option values if you wish (cf CUE, Dhall). If your mental model of your system is more abstract than the configuration of each individual service, it’s not hard to write it down as Nix code that defines some new NixOS options, then define your system—or several—in terms of those options.
Bad parts:
Apart from the build system as such, the CLI includes support for a lot of the idioms I mentioned above, so the separation may not look that clean. (This is not helped by the fact that a complete CLI overhaul is in progress, with old commands like nix-build and nix-env being superceded by a single new one, nix. The nixos-* ones are separate for now.)
The language is perhaps a bit too minimal and lacks a standard library, so Nixpkgs ends up containing that as well, without much in the way of documentation. You will have to refer to the source there. The library is mostly simple list and mapping utilities, so it’s not difficult, but figuring out whether the thing you want is in it or not can be frustrating, and the API won’t win any beauty contests.
> Other than integration with the rest of the Nix/NixOS ecosystem
Nix/NixOS is the big deal actually. NixOps is just icing on the cake. A NixOS installation is configured by building/copying over a system profile, and then activating it.
With just NixOS, you edit a configuration file on the server, then run a command that will build a system profile from that configuration and activate it.
With NixOps, you have configuration files on your workstation, and run commands to build the system profiles, copy it to the servers, and activate them. Of course you can do all of this without NixOps. It just makes certain things easier.
Puppet and others can do all of this, too. However state transition tend to be the weakest link (e.g. tell Puppet to provision a brand new server vs one that has run some other stuff, how sure are you that the resulting systems are the same?). Nix/NixOS takes care of that (most of the time anyway -- there are still things like data migrations that applications have to take care of).
My personal administration involved a lot of digging through installed software's FHS to figure out how things worked. Especially coming up through Slackware. It's probably a learning style thing.
Mutable distros you directly edit stuff in /etc, then build your knowledge on top of that foundation. Whatever better practices you end up adopting, you're still ultimately modifying files in /etc (and probably elsewhere). A NixOS beginner shouldn't be touching config files, and can't even do things like replace a binary with a shell script wrapper to understand when and how a program is run by a different program.
So I see that departure as a pretty huge one, that will affect someone learning Linux on NixOS for many years, as they need to dig through NixOS specific docs to understand how they're supposed to configure something, rather than falling back to the regular packaging docs. Whereas with Debian you only need Debian documentation to know how to install a package, but after that the upstream package documentation tells you everything else.
As an aside, I feel like NixOS asks a fundamentally different question - "how can we mitigate Linux/Unix's complexity" rather than the traditional mutable distro question of "how can we best interact with Linux/Unix's complexity".
(Also, that sounds like a great approach to explaining NixOS!)
It's like Nix-Darwin but without any setup issues, spared from breakage related to OS upgrades, but also with fewer escape hatches (Flatpak is the main easy one it does provide, also steam-run) for app installation. If you do enjoy Nix-Darwin once you get it going and you at least somewhat enjoy Linux desktops, you'd probably enjoy it as a daily driver.
I would say that for users new to the Nix ecosystem, NixOS on a spare machine is the most gentle and pleasant way to introduce the module system and declarative Nix config. It tends to be smoother than Home Manager or Nix-Darwin, and it's a lot more complete than either, both because it has more users. But a spare machine is a good choice for those who aren't yet sure that they like or care about Nix, because if something is missing or non-obvious, the only way out is through— you have to dive deep.
NixOS is so mature these days compared to when I first picked it up, though. Packaging work just to get by on the day-to-day is way more rare, and there are a lot more examples around. A Linux hobbyist who is prepared to struggle a bit can definitely just dive right in and have a good time, for sure.
I've bounced off Nix a couple of times and figured that the problem is that it was too different. A lot of Linux distros (especially post-systemd) have a fair number of similarities and it's pretty easy to translate knowledge between them. NixOS _probably_ works very similarly, but it's also got this additional declarative configuration layer on top, which is the point of using NixOS, and it's got its own special way of doing things.
You can't translate Linux knowledge to a NixOS config directly, you need NixOS' documentation to understand the "NixOS Way" of doing things, and the NixOS way of doing things does not translate into other distros. And the documentation is difficult to understand and at times seemingly arbitrary.
You have to commit to learning NixOS and understand that you are only learning NixOS, it won't help you use anything else. Other Linux distros help you learn Linux in general and inform your understanding of Linux system construction, but NixOS is its own thing. Plenty of people learn NixOS anyway, and more power to them, but it's definitely pushed me away.
> Using nixos as a daily driver doesn't make sense to me
Many Nix enthusiasts use NixOS as a daily driver, and are very pleased with it.
I'd say some of the advantages are: the same 'elegance' from being able to declare how a package gets built carries over to being able to configure a system. -- e.g. for niche things like "setup Yubikey with PAM", I don't have to worry about what config settings to manually change, I can just update my config with that. (And my config is in a git repo; whereas "what changes I made" is not).
There are certainly significant drawbacks, sure; but I think the main decider between whether it makes sense is how appealing "take the time to write a config with changes" is vs "just run the command / edit the system file" is.
Except, most of a nixos system is built by simple Autoconf scripts and some env cars being set correctly.
I mean I built a whole nix distribution for embedded devices with runit as init and cross compiling and everything and nix made it easy and fun. And I learned that it's just Autoconf and shell all the way down. There's no magic to nix. The most voodoo non standard thing they do is patchelf stuff, but most of the nixos specific stuff is just setting paths to configure scripts or in the environment.
> these are shared Nix configurations between macOS, Linux, and WSL on Windows
This is the "killer app" of Nix for some people. I've got a lot of machines, spread out between a variety of usecases. With Nix, I can have individual module files for my desktop apps, my gaming software and my terminal configuration, then link them into the various machines that need it. Once it's fully set up, you can essentially manage the environment of dozens of different machines in a single Git repo.
Nix will frustrate people because it doesn't offer a lot of imperative or immediate solutions to things. If you can handle the learning curve though, you'll be hard-pressed to find a more comprehensive package management solution on any OS.
You're looking at a solid 10-20 hours of hacking stuff together to get a decent working system, and you still won't understand a good 80% of what you copied from various repos.
I've been using NixOS for a year now, and I have a definite love/hate relationship. Many times I miss the simplicity of Arch, where I understood _everything_ about my system and how it was configured.
NixOS is like learning everything all over again, but in a weird, poorly documented language+standard lib that nothing else uses.
I think when you are super comfortable with it, is when it becomes truly amazing. But that takes a lot of dedicated time and effort.
I bounced off NixOS a few times as well. In addition to what you've said, I also didn't find it compelling because I already had a way of doing programmatic configuration and functional system management under Debian using my own scripts. So I didn't particularly see what converting everything over to NixOS configs would get me.
What made NixOS stick is running up against some problems where Debian itself was ill-suited and seeing Nix's power. For example, building an image for a Raspberry Pi can be done with a handful of config lines. Changing between a cross compile and an emulated compile is also a handful of lines. This kind of power feels akin to the general lisp / functional curse where certain things become so easy they aren't even well documented because once you understand the system it's second nature.
Another benefit - I've modified kernel source and I've written my own modules, but they always fell by the wayside due to the maintenance burden of a compiling a custom kernel package. With Debian, I would end up reading kernel source plenty of times to figure out what was going on, but it was effectively read only. Whereas with NixOS, adding kernel overlays is straightforward. Using what is essentially a source distribution plays to the larger philosophy of Free software.
> A huge advantage of using a configuration management (CM) tool is that they're "idempotent". Idempotency basically means that you can run the directives over and over again safely.
They're idempotent only as long as the configuration stays the same. If you removed this "apt: package=XXX state=present" line, XXX is not going to be magically uninstalled, but you may have a nasty surprise the next time you attempt to provision a second server with the same configuration and realize you're missing a runtime dependency. That's what I find fascinating about NixOS/NixOps: you can describe the entire state of the machine in a single configuration file (if you use the declarative style of package management). Of course, it won't help you if:
- you already have a large number of non NixOS systems
- you need many packages not present in NixOS
- you'd like polished package management (the Nix package management still has a way to go before it reaches yum/apt ease of use)
NixOS feels great, I love it. The only gripe I have with it is the inability to just run a custom binary on it. For me the explanations on how to get it to work or write a ?Nixpkg? file was not very clear. Now I'm back on ubuntu and missing the simplicity of NixOS, everything was just so simple and light. I've used ubuntu, arch, manjaro and elementeryOS before, but NixOS felt the nicest.
I don't want to distrohop anymore, Arch was awesome and NixOS feels like the next step. But it doesn't really feel ready for a (maybe) less experienced user. It feels a bit like gentoo in the way that you need to re-link the libs for non-nixos packages or package a binary you just built yourself.
I think the thing I'm going to try next is PopOS with only the Nix package manager, it feels like a good middle ground between living in configs and no hassle with non-entry level documentation.
I've also switched from Arch (has been on it for ~10 years) to NixOS (~1 year so far), and fully agree it's amazing.
I've been thinking how interesting it would be to create a user-friendly Linux distribution on top of standard NixOS (similar to what Manjaro is to Arch), which would not require learning Nix language or tinkering with the configs. I mean, system configuration/choosing packages/drivers/kernels should not really require a user to write in Nix language - the sane choices can mostly be represented by a set of GUI checkboxes. There also could be GUI utilities for other Nix goodness, such as creating nix-shells with necessary dependencies available, declaring wrappers for proprietary software, or building temporary VMs. So, I would say, the user absolutely does not need to know a lot about Nix to fully appreciate robustness of NixOS way, and in principle, with the right tools/GUIs it can be very approachable for even non-technical users - it's just that user friendliness seemingly has not been a priority so far.
NixOS is not for the impatient. Maintaining your system configuration is an exercise in software development like any other - if you lack rigor or discipline, your codebase will become painful to work with. Nothing is ever one shell incantation away - it has to be carefully architected into the existing system.
That being said, once you get the hang of things, you reap amazing benefits:
- You can clone your system to any machine, and immediately have an identical environment
- You can share system configurations as code (declare the means for hosting a website in its repository, for example)
- You can use a fully-fledged programming language to configure any part of your system
- You can make use of an extensive ecosystem of easily composable, prebuilt NixOS modules
- You can seamlessly integrate with Nix, allowing for ephemeral development environments and shells with packages, eliminating much of the need for imperative package management
- Everything in a Nix-based system must be derived strictly from (lockfiled) inputs, making the reproducibility guarantees incredibly strong (barring any network errors or resources being taken down)
- The declarative nature of anything Nix-based means that every change is documented - your system never shifts from the source of truth, compared to other distros where discipline is required to maintain reproducibility
- Nix is so robust that you could even nuke your filesystems on every log out, if you'd like
Sure, but Nix is very weird, and takes quite a different approach compared to other things. Understanding Linux is both necessary, but not sufficient.
But comparing Arch an NixOS:
- Arch requires more elbow grease than Ubuntu. NixOS requires more elbow grease than Ubuntu. I wouldn't recommend either to beginners.
- On the other hand: NixOS is immutable and pure, whereas Arch is a system that can be beaten into shape. - Or the Arch Linux wiki is fantastic, and Nix documentation is .. all over the place.
(Maybe AUR is better than Nixpkgs; but ultimately nix is a much more powerful tool than pacman strives to be).
On both NixOS and Guix System you can get by pretty well without learning the config langs or all the more advanced features. Only really becomes a problem if you need something new packaged. You can enjoy declarative package management with easy rollbacks without really learning more than any other distro.
I love it, but I'd hold off on recommending it outright for everyone. There's a learning curve to be sure and if you run software not provided in its packing system it can take time to port to the Nix way
Just about everything in a NixOS is configured in a declarative way, but that only really scratches the surface. It's the first Linux OS I've used that configuration is done at a wholistic level
Say for example you have a RHEL/Debian Linux server and you want to see how it’s configured. This sounds easy, but can be quite time consuming. You can see what packages are installed but then you’d need to examine all the /etc files. Try and see which ones are modified. Look at all services, look for further configuration that may exist in /opt or /usr. When you get to a certain scale tools like Chef, Puppet or Salt tend to help with managing configuration. Over time to meet compliance and monitoring requirements configuration can grow. And that’s not getting into any filesystem permissions you may set.
If you're using `yum install` or `apt-get` to install packages out of the system repos, you'll get the latest package in that repo. Run that command at different times, you can get a different package version
In NixOS the system and packages are versioned together; makes for very reproducible systems. The downside/upside (depending on your needs) is, updating your kernel will update your packages in lockstep
With NixOS, you can configure a complete system with a single file making Chef, Puppet or Salt obsolete. Once you get over that first hurdle of using NixOS and moving your workloads to it, it tends to be easier to maintain
The major downside I run into is that most of the world does not use Nix[OS]. So if you need something not provided by Nix[OS], you’ll need to learn how to make your own package (derivation)
There are many caveats to everything I said above, but its the general idea
Zero to Nix and its NixOS section is elegant and simple.
It has already been said many times but NixOS suffer from a poor and a fragmented documentation.
The Official Nixos Manual is a very good start to install Nixos. But that's it.
It does not explain all the logic behind NixOS for already experienced user. Because yes, Nixos is absolulety not for beginners !
Nixos is a kind of blackbox where once you've luckily found the site https://search.nixos.org/options it comes with all the options you were looking for.
You need a sysadmin background to understrand theses options like (ie: services.nginx.virtualHosts.<name>.locations.<name>.extraConfig). A reverse dictionary of how we used to do things with traditionnal distro and how to do with Nixos should be a very good start !
At least, the extrem big fucking issue is the complete mess between Nixos/Nix/Flake/Home Manager. Theirs documentation and definition are often "recursive dependant" in a way you are completely lost.
If i compare to AUR (ArchLinux User Repository), the learning curve to create a custom package is quite easy. For Nix, it requires an amount of concentration, reads and skills to do the same. This discourage users.
That's true. Once you have found your footing with the Nix language and figured out some basics of how to navigate the NixOS modules in Nixpkgs, the latter becomes a rich source of examples on how to configure everything on a modern Unix-like system, from mounting a btrfs subvolume in your initrd via systemd/dracut integrations to setting up PipeWire to emulate PulseAudio. But while NixOS can still teach you a lot about how a working Unix-like system is put together and how its stack is configured, the most useful point of entry for such exploration is very different from what you might be used to on other distros.
You can also learn by exploring the Nix profiles and the Nix store of a working system, much like you would walk through the FHS on a ‘normal’ Linux system— after all, all of your system-wide config files can eventually be hunted down in the Nix store. If you run `ps` on a NixOS system, you'll see explicit references to RC files for lots of programs that are wrapped to point to specific config files, and for running persistent services. But it's probably not as useful as going directly to the Nixpkgs source, once you've learned to read a little Nix.
> A NixOS beginner shouldn't be touching config files, and can't even do things like replace a binary with a shell script wrapper to understand when and how a program is run by a different program.
That's an interesting thought. I didn't come to NixOS as a beginner in the Linux world; NixOS was not my first distro. (I think that's true for most of us in the community.) With NixOS, neither the paradigm nor the community really encourages the kind of monkey patching, that kind of learning by brute intervention on a running system. Even so, I think it would be possible (if perhaps a bit perverse) to write a textbook or a course like ‘Learning Unix with NixOS’. I think using a read-write store as a teaching tool before showing the reader how to use Nix itself to wrap programs that live in the Nix store would be fine.
> [NixOS users] need to dig through NixOS specific docs to understand how they're supposed to configure something, rather than falling back to the regular packaging docs.
Right, NixOS definitely changes the sort of ‘order of recourse’ users will want to make when configuring a piece of software. I'd say it looks something like this:
If the answer to (1) is no, or the answer to (3) is yes, then it's definitely necessary to consult the upstream documentation on the software you want to use. In the case that a module exists but you need special config, there will always be a way for you to pass configuration options defined upstream directly to the application through your NixOS configuration.A NixOS fanatic might frame this
> Whereas with Debian you only need Debian documentation to know how to install a package, but after that the upstream package documentation tells you everything else.
in an alternative way:
> Whereas Debian only helps you to install the package, NixOS will also help you perform common configuration tasks. It's only when you need to perform peculiar configuration tasks for your specific needs that you really have to dive into the upstream documentation.
At the same time, knowledge of some upstream component (e.g., Xorg, connman, OpenSSH, etc.) always remains applicable with NixOS, if you want it to be. Everything that's configurable under /etc/something/or/other on Debian remains configurable on NixOS in a straightforward way, either by specifying key-value type config in the Nix language or (in the worst case) by embedding a config file snippet in your NixOS configuration.
> As an aside, I feel like NixOS asks a fundamentally different question - "how can we mitigate Linux/Unix's complexity" rather than the traditional mutable distro question of "how can we best interact with Linux/Unix's complexity".
I think this is well put, and it's what I was getting at above with the idea that thinking about the particular structure of some program's RC file is a last resort in NixOS. But it's not entirely one-sided! The NixOS module system serves not just to shield users from that complexity when they don't need to confront it, but also to teach them about it when they do. For me, that's one of the reasons that learning the Nix language and exploring the Nixpkgs codebase is so worth it.
reply