
Reflections on NixOS - ikhthiandor
https://zenhack.net/2016/01/24/reflections-on-nixos.html
======
dbcurtis
People need to stop thinking of NixOS as another Unix-alike, because it isn't,
in very much the same way that MacOS used to be a Unix-alike, but isn't any
more, either.

NixOS is rebuilding important pieces of the foundation. Why? To address a
basket of problems we have been complaining about with Unix for a very long
time. Is it worth the hassle? Well, have you ever lived through a kitchen
remodel in your house? That's a hassle, too, but you end up with a better
kitchen.

IMHO NixOS is pointing the way forward, but is probably not the last word in
next-generation operating systems. The existence of NixOS and Guix (and
similar) are exciting, because they are part of the ferment creating the thing
on which we will eventually converge.

~~~
adamnemecek
Why isn't macOS a Unix-like anymore?

~~~
skrpwr
macOS is BSD Unix under the hood with the Mach kernel [1]. I'm tired of
hearing this nonsensical talking point that macOS has strayed too far to be
considered Unix. What does that even mean? Perhaps someone should inform The
Open Group who controls the official Unix specification that they are wrong.
Even though it shells like a unix, users like a unix, signals like a unix,
files like a unix, networks like a unix, streams like a unix, and threads like
a unix, because of reasons never enumerated, macOS is not Unix. /endrant

[1]
[https://developer.apple.com/library/mac/documentation/MacOSX...](https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/OSX_Technology_Overview/SystemTechnology/SystemTechnology.html)

~~~
dbcurtis
A kernel is not an OS.

I'm thinking perhaps some measure of porting effort is the appropriate metric.
There is a reason Mac users can't simply point to a bsdports repo.

~~~
warmwaffles
Uh, yes it is. It is a very core part of an OS. Without it, the OS does not
function.

~~~
dbcurtis
Kernel is necessary, not sufficient. Nobody ships just a kernel and calls it
an OS.

~~~
warmwaffles
Right, linux never just ships as a kernel for others to consume.

------
mbrock
I use NixOS since last spring and I adore it so much that I almost credit it
with making me like computers again.

It's a kind of bumpy ride sometimes but for me there's no other distribution
that's even close. Packaging the Nix way does require patching upstream and
that's probably inevitable.

It would be nice to help with the documentation situation, though I'd note
that the NixOS manual and the Nixpkgs manual _are_ seriously helpful and quite
comprehensive; it's just that there's another type of guide that would really
help.

~~~
radarsat1
> Packaging the Nix way does require patching upstream and that's probably
> inevitable.

Not to familiar with Nix, can you explain why? Anything that can't be handled
simply by applying small patches to the upstream during packaging?

~~~
jorams
"patching upstream" in this context means "applying patches to the upstream
during packaging".

Nix and Guix require programs to work with a directory layout that differs
significantly from the standard. Simple things like `#!/bin/python` don't work
anymore, because they aren't explicit enough.

~~~
mbrock
Yeah, thanks. To add to that, the Nixpkgs "standard library" includes lots of
convenient tools for patching like this, and much of the common stuff is done
automatically by the standard package function. The #nixos IRC channel is a
good place to ask if you run into trouble when packaging something.

Generally, making NixOS packages is really delightful. Even the patching stuff
is straightforward and easy to use. Now that I've learned the basics, I
routinely make small packages.

With many typical packages the _only_ thing you need to do is specify how to
fetch the source, plus the list of build dependencies, and there are built-in
functions for fetching from HTTPS or Git.

------
bendlas
Avid NixOSer here. While it's sad, that we're not there yet in terms of user-
friendliness, I still think, given the radical approach, NixOS takes, it's
increadibly feature-complete. I find it easy to tweak, too, but that might be
due to previous experience with functional systems.

For the specific suggestions in the article, I'm not convinced that they are
possible, while retaining the same benefits:

\- Filesystem snapshots are not enough to deal with, e.g. slightly different
builds of the same shared library

\- Namespaces, however are. In fact, there is buildFHSEnv in nixos, to take
advantage of those.

\- Hiding of runtime dependencies is done with the intent to minimize
"accidental success", because that leads to unstable systems.

\- Also a package could, e.g. depend on a patched version of Python2.7, that
you'd never want to accidentally end up on the system path.

Having packaged some, I do feel the author's pain though. I wonder, if we
couldn't get rid of a lot of upstream grind, by encouraging usage of fhs-env
namespaces.

~~~
eliaspro
I think the right term here instead of "filesystem snapshots" here is "btrfs-
like filesystem subvolumes" which are reflinked CoW volumes based on a
snapshot.

------
iElectric2
Disclaimer: I'm core NixOS developer

It's great to see such articles as they dive deep into psychology when it
comes to new technology. It's really hard to unlearn.

It takes effort to realize that the promised gain is bigger than the pain
coming from doing what we're used to doesn't work.

~~~
infinity0
It sounds like you're blaming the users for not "unlearning" enough to be able
to use NixOS.

As long as you have that attitude, you'll be driving away users. How do you
think you can improve your software to make it easier for users to "unlearn"
stuff you think is bad?

~~~
Filligree
As a near-fanatic NixOS user (now!), I agree with both you and GP. The
learning curve is brutal, so it took me a while to get started, but it's paid
off several times over.

It's unfortunate that humans can't trust each other enough that saying "You'll
like it after a few months" is good enough, but it's also an inevitable fact
of life; for starters, the speaker might be mistaken. I don't think NixOS is
for everyone, at least not yet.

And it's hard enough to run arbitrary software that, yes, you do need to learn
the Nix language. In most cases it's as easy or easier to package the
application for NixOS than it is to run it without packaging, which on the one
hand is a benefit to the Nix ecosystem, but on the other hand can be a little
annoying. There are workarounds...

But the workarounds require some unusual understanding to begin with.

I think one of NixOS' major flaws at the moment is documentation. There's the
wiki, but it's both somewhat outdated and very much not comprehensive. As for
Nix, it's been best explained in a series of _blog posts_ , and as good as the
Nix Pills series is, you have to find it before you can read it. It's also
somewhat short on HOWTOs.

Most people don't like to spend hours writing documentation, though.

The existence of NixOS, and work done on it, is a massive positive
externality. Even if it doesn't catch on, it's going to inspire half a dozen
clones in the next decade or two. Unfortunately I don't see a good way to get
more effort put into it, especially the boring bits (such as documentation)...

I suppose this comment is my way of trying to change that.

~~~
zeendo
Would you suggest the Nix Pills series now? I notice it's 2 years old.

~~~
akavel
As a "common user", I'd say _very much yes_. It goes quite deep into the
internals, and touches underlying ideas and basic mechanisms of Nix, which I
don't think are expected to change [ever].

That said, note that it starts to be relevant when you're starting to _write_
Nix expressions (meaning, write something in Nix language). Sometimes also
when you want to read them and understand them. Which... is probably quite
soon after starting to use Nix/NixOS, if you'll want to tweak some configs or
add custom new packages. If you're really, really just doing first steps with
Nix/NixOS, and/or just use the default packages with only simple tweaks, I'd
say you don't need to read it _yet_ (I personally wouldn't grasp enough basics
then to understand WTF the articles are talking about at that point).

------
chriswarbo
As a NixOS user I've certainly encountered some of these issues. While Nix and
NixOS are really nice, the first thing I'd recommend to a new user would be to
learn the Nix language, as it's pretty much a requirement for getting anything
done.

I agree with the author that per-user configuration is a bit overkill for the
common use-case of a single user machine, but you have to go out of your way
to use it (via the "nix-env" command), so I think it's a bit of a non-issue.
Since Nix can be used from any user's home directory anyway (this is often how
it's used on non-NixOS systems), it's not necessary for Nix/NixOS to contain
this per-user feature; however, by doing so they gain a huge space
optimisation by re-using the same store. The same can be said for NixOS
containers, which I don't use but I see why it's there.

As for making packages available at runtime, that's what the
"propagatedBuildInputs" attribute is for. Sometimes Nix can actually
automagically figure out runtime dependencies, since it looks through files as
they're installed to see if they contain references to other store paths; if
so, those paths are added to the runtime dependencies.

~~~
bennofs
No, that is _not_ what `propagatedBuildInputs` is for. `propagatedBuildInputs`
should be used very sparingly, in most cases wrappers are the better solution.

For example, consider if every package that contained bash scripts would put
bash in `propagatedBuildInputs`. Then I could not use a different version of
bash for my user environment than those packages I installed used!

Also, `propagatedBuildInputs` are not even propagated into the user
environment, the attribute that does that is `propagatedUserEnvPkgs` (not sure
if that name is fully correct), and it is very sparingly used within nixpkgs.

~~~
chriswarbo
> `propagatedBuildInputs` should be used very sparingly, in most cases
> wrappers are the better solution.

propagatedBuildInputs is a widely-applicable hammer, and the article's tone
made it sound like the author wanted a quick fix. Wrappers certainly provide a
better outcome, but require more thought and case-by-case caveats; i.e.
they're more appropriate for widespread adoption in nixpkgs, but not so much
when throwing something into packageOverrides to stop a build script
complaining.

> For example, consider if every package that contained bash scripts would put
> bash in `propagatedBuildInputs`. Then I could not use a different version of
> bash for my user environment than those packages I installed used!

Well, wrappers aren't the answer here either; fixing up the shebangs is.
Functions like stdenv.mkDerivation will do that automatically.

I've not come across propagatedUserEnvPkgs before, but I also don't make much
use of the user environment. I spend most of my time in nix-shells :)

------
lallysingh
I used arch for a long time, but got tired of having to fix things every time
I upgraded the box. And got tired of having to upgrade the box every time I
wanted to install a new package, and found that my installed version of arch
was too old.

Nix's language is a giant PITA. But the box runs quite solidly. Hell even my
nvidia optimus works - for the first time on any distribution.

For things that don't work well, I shove them into a docker image. Like the
arduino IDE.

------
lil1729
I used nixos for a few weeks and then went back to Debian.

* I share the concern of the author on symlinks farm. It is scary! I would like it to be dealt with in the filesystem layer (Plan 9 had a snapshot based filesystem - fossil - years ago). Symlinks have all sorts of weird semantics on different Unix machines.

* Another of my gripe with nixos is that it makes Unix, a single user machine! Sure, packages need not be installed in a user-local way. I may be ignorant of other possibilities here.

* More care for licenses. I still use Debian because they really care for licenses. Last I looked, nixos was in no way close to Debian in terms of documenting the various copyrights and licenses of files pertaining to a package.

Otherwise, Nixos is a great idea and a huge step forward.

~~~
chriswarbo
Regarding licenses, most (all?) packages in the official nixpkgs repo have
license metadata, and you can set your configuration to forbid/allow
proprietary packages (the "allowUnfree" option), or use a whitelist (e.g.
forbid everything except Flash).

Guix is a GNU project, and doesn't allow proprietary packages in their
collection at all.

~~~
lil1729
Yes. But the amount of information in the debian/copyright file is a lot more
than just one scalar flag. I think that level of detail on the licenses is
extremely important.

------
jxy
PLAN9 namespace is a perfect solution for this kind of package isolations. I
can imagine a perfect NixOS plan9 hybrid, only if APE were good enough.
Perhaps people(TM) should really pool resources together and make that happen.

~~~
xj9
It's very early in the project lifecycle, but that's along the lines of what
I'm planning for my hobby OS[1]. Right now I'm planning on using Genode/seL4
for the kernel and doing a plan 9-style userspace in Rust. Genode has a Linux
virtualization/compatibility subsystem that I hope to use to bootstrap Linux
"flavored" namespaces.

[1]: [https://www.heartcore-os.org/](https://www.heartcore-os.org/)

------
bfrog
funnily enough I tried the same sort of switcheroo a few weeks ago as well and
just ran into too many issues for it to be useful for me at the moment as
well. I tried to contribute back fixes for the the problems I ran into, but
just couldn't figure out how to fix all the problems I had with the way things
were being done :( PostGIS and a few Gnome 3 desktop issues basically drove me
back to Arch where stuff just works.

I'm sure I'll try nix again, and again, until maybe one day it just works as
well. I really do love the features it brings not just on paper but in
practice.

~~~
fizzbatter
Yup, same. Nix was awesome, and i was convinced that for my laptop (OSX) and
my home server, it was all going to be NixOS and Nixpkgs from here on out.

Then i started running into external dependencies.. one after another, having
to patch them to make them work with nix.. it was just such a headache, and
honestly i was in _way_ over my head. I am not that well trained of a linux
user, but Nix sort of required me to be. So, i had to backoff for now.

I really hope i can use it again soon.

------
gravypod
Correct me if I'm wrong but isn't the better solution to this
containerization? The application will in a literal sense own the system.

You also get inherent security (unless someone figures out how to escape their
vm).

I member someone had a website talking about this. The use of a file system
with revision tracking, containerization for security, and sending files
between VMs to make things work.

~~~
seagreen
The great things about NixOS is that you can describe the entire state of your
system in configuration files, and then after running `rebuild` know that
what's on your computer _exactly_ matches that configuration.

Can you do that with containers?

For instance, I'm on NixOS `16.09.git.20f009d (Flounder)`. Here's my
configuration:
[https://github.com/seagreen/vivaine](https://github.com/seagreen/vivaine). I
know my machine exactly matches the combination of that NixOS version + those
config files. My impression is that this is messier with containers because
while you can make a snapshot and know the snapshot is frozen, as you modify
snapshots over time they'll begin accumulating cruft due to things like
installing programs, uninstalling them, snapshotting, but still having some
leftovers from the install. I'd like to hear from someone with more container
experience here though.

~~~
gravypod
Is there any real advantage to that opposed to say running this on my arch
machine...

    
    
       yaourt -Qe|grep -v "(base"|grep -v "(xorg"|grep -v "lib32"|cut -f 2 -d "/"|cut -f 1 -d " " > package_list.txt
    
    

Then to reinstall...

    
    
       pacman -S package_list.txt
    
    

And copy in my home directory. After a reboot everything should work the same
way I have it setup (I keep every change I possibly can in my home directory.
It's everything aside from two scripts that aren't actually needed)

The difference is I generate my config via usage, not via definition. I don't
actually know what I need to use my computer, I've just always used it. I can
back everything up and create essentially the same machine (since my distro
Manjaro is rolling) every time I need it.

For me, this is a solution that is a bandaid fix for a completely different
problem: the lack of rolling distributions and the lack of storing old
versions. These are both package manager and os developer problems. Once we
leave the space of OS revisions rather then having "The OS" and having it up
to date or out of sync with the main os we will fix these problems.

I don't know, am I seeing something wrong?

~~~
aseipp
You don't get features like transactional rollback to prior revisions of your
system definition, which is never an important feature (until it suddenly is).
This also seamlessly allows non-privileged multi-user package management
without duplication of programs or anything like that, so you don't need to
poke your system admin or alternatively pollute $HOME (and in turn pollute
your bash/zsh config for library paths, require fixing up include paths for
anything you compile using $HOME stuff, etc). This feature is actually
particularly important, because it allows you to set up individual, 'hermetic'
(or 'pure') build environments for every project, using 'nix-shell', even on
multi-user machines.

If the project supports Nix, you can just go in and run 'nix-shell', and your
machine is magically populated with the needed dependencies to build it (or
using already existing ones), and you drop into a new `bash` with a cleaned
environment and custom $PATH for that project. You can then leave that shell
(after you submit your patch to an upstream project or whatever) and garbage
collect the installed dependencies.

The model also permits things like transparent, remote multi-
system/architecture builds (why build the Linux kernel in my chosen
configuration on my laptop when I have a 16 core server somewhere else, why
SSH into my OSX machine to run a build when Nix can do it with the same
description, etc,) -- and in the future when binary determinism is worked out,
a single checkout of the Nixpkgs repository will (hopefully) be able to serve
as completely-reproducible build chain, allowing anyone to produce identical
binaries and identical Nix packages. (And since Nix works on any Linux system,
you can run that build anywhere).

NixOS of course supports general container technology as you mentioned in your
first post, so you can also use that to your hearts desire.

In practice NixOS is quite powerful but there are still many glitches and
user-facing UX issues that are problematic. It is definitely not for everyone.

------
seeaje
Trying to set NixOS on a armv7 board (NVIDIA Jetson Tegra K1), There is a
customized linux 3.10 kernel that comes with the board and I'd like to know
how to integrate that on NixOS. Currently I managed to boot the board using a
generic armv7 image which runs on SD card I got from this page -
[https://nixos.org/wiki/NixOS_on_ARM](https://nixos.org/wiki/NixOS_on_ARM) .
But I cannot activate any services like ssh or install drivers like nvidia,
cuda iwlwifi and bluetooth on Nix. Any support will be appreciated. NixOS
manual doesn't explicit between different architectures and I think it's
mainly written for running NixOS on amd64 PCs or similar architecture but not
arm. What am I missing here, where should I look into or read about to set a
properly running system on my arm board? Thank you!

------
majewsky
So this probably just saved me a trip down NixOS road, which was on my (ever
too long) todolist for some time now.

Last year, I finally put my private systems under configuration management,
but just like the author, I was concerned that both the configuration
management tool and the system package manager like to exert complete
authority over the system without knowing about each other, a recipe for
disaster.

In the end, I wound up writing my own configuration management tool, Holo [1],
which relies on system packages to install applications and deliver
configuration files, and implements the additional logic to provision things
that the package manager does not understand (users, groups, SSH keys, etc.).

One thing that's missing from Holo right now is a validation pass that the
whole system matches the expectation described by the configuration packages.
(Right now, only files that were touched by Holo can be monitored for changes,
but not files installed by the package manager.)

But it turns out that that's a hard problem. A normal Linux system has a lot
of moving parts that are not accounted for by the system package manager. See
for example the positively huge list of exceptions in [2]. Of course, the bulk
of these quickly-changing files are data, which can be skipped easily by just
ignoring /run, /tmp, /var/cache, /home and so on. The question remains what to
do with the rest: implement some sort of parsing for auto-generated
configuration like /etc/passwd, /etc/ssl/certs and so on, or just rely on
snapshots of known-good states designated by the administrator? I'm still
undecided.

[1] [http://holocm.org](http://holocm.org) (the site seriously needs an
update)

[2]
[https://github.com/graysky2/lostfiles/blob/master/lostfiles](https://github.com/graysky2/lostfiles/blob/master/lostfiles)

------
CyberShadow
Not sure if I'm reinventing the wheel, but incidentally I've been working on
this lately:

[https://github.com/CyberShadow/aconfmgr](https://github.com/CyberShadow/aconfmgr)

It's like basic traditional configuration management, but it's two-way: it
takes the difference between the user-managed configuration and the current
system state, and rectifies this difference by either editing the
configuration or the system. A second invocation is a no-op. If your
configuration is in version control, this allows easily tracking any
unaccounted changes to the system.

------
tombert
I used NixOS for about six months, and while I think the core of NixOS is
great, but I never liked KDE and how much it kind of forces it on you.

Gnome support is kind of horrible, and it felt like I either had to commit to
something incredibly low-level like XMonad, or KDE.

~~~
vertex-four
I don't think many NixOS users use desktop environments, generally speaking,
and NixOS users tend to wind up being NixOS contributors as it stands right
now. XFCE's available, though, for something lightweight.

~~~
tombert
I mean, the Live-CD has KDE running by default, so I kind of assumed that was
the standard.

~~~
Filligree
It had to have _something_ , right?

There's no 'standard', but KDE is used more often and therefore has fewer
bugs. XFCE works fine. If you want Gnome, well, I haven't tried it, but they
always welcome patches.

------
VT_Drew
Am I the only one that caught the homestarrunner reference?

