
A Nix terminology primer by a newcomer - signa11
https://stephank.nl/p/2020-06-01-a-nix-primer-by-a-newcomer.html
======
seddona
I'm a longtime Ubuntu user and recently gave NixOS a try as most of our team
use it. I have to admit I was highly skeptical as it all looks very
complicated. The learning curve was a bit steep due to the documentation and
odd terminology. But after you get going it solves so many problems. The fact
you can declare you're entire desired set up in a single configuration.nix
then "nixos-rebuild switch" and you're done saves so much time.

~~~
samvher
I tried to fully switch my work environment to NixOS 2 or 3 years ago. I
really like the concept and I think it's a very good approach to reproducible
build environments, in theory it's much cleaner than the massive data
replication you get with e.g. Docker.

I only lasted for a month or two though, for a couple of reasons. The main one
was that I had a lot of trouble with Python packages - Nix suggests a certain
approach for dealing with them which didn't work very well for me and I didn't
manage to set up an alternative that I liked. (For Haskell I loved working
with Nix though!) A lot of software I use also wasn't available in the
repositories and I tried to build some packages but found the Nix language a
bit obtuse. The basic syntax and logic are not too hard but I still found many
of the packages I used as examples very confusing.

In the end I'm back to Ubuntu using Docker whenever I need reproducible
environments.

------
carlmr
I've been trying to get a nix file running today, and the terminology
definitely gets arcane very fast.

I also have the feeling that the tutorials start with the details, instead of
starting with an overview so you can understand what is what.

This is guide us already very helpful and I think one should read it before
the official tutorial. Thank you!

~~~
clhodapp
_I also have the feeling that the tutorials start with the details, instead of
starting with an overview so you can understand what is what._

When you are trying to be as different from everything else as wide-reachingly
as Nix is, it seems to work better to build an understanding _up_ rather than
_down_. This seems to frustrate a lot of people because it does not give much
payoff for the first few hours of learning (and that's a lot to invest to even
understand what something is). The truth is that Nix is really really
complicated (expect a year-long learning curve to truly "get" everything), but
it's also really hard to take the more-standard approaches to building
packages and managing machines seriously once all the pieces finally do all
connect. Unfortunately, it kind of makes one feel like being an early adopter
of git in a world where no one else uses version control. It's like, "Yes,
this is way better, but I'm not going to be able to get anyone else to use
it."

~~~
nvarsj
This is well described. Nix is fundamentally a different way to manage an OS
compared to almost anything out there. While I think the ideas behind it are
revolutionary and is the right way to build infra, the UX and organic growth
of it makes it fairly difficult to get into - so there is unfortunately a
steep learning curve. I think I sunk a solid 40 hours into building a
declarative config for my own dev machine before I had a decent (but far from
complete) understanding. But once you grasp it, it is quite mind blowing, and
you wonder how anyone could cope with traditional mutable systems and the
associated temperamental config management.

I think Guix might be the answer as a more approachable implementation of the
Nix ideas, using Scheme for its config language. I haven't spent much time
with it but I got going a lot quicker initially compared to Nix.

~~~
takeda
> I think Guix might be the answer as a more approachable implementation of
> the Nix ideas, using Scheme for its config language. I haven't spent much
> time with it but I got going a lot quicker initially compared to Nix.

Out of curiosity, did you tried Guix before trying Nix or vice versa?

When looking at Guix myself, all I see is that the derivations are just
wrapped in parentheses otherwise they do look similar. So I'm wondering if
scheme actually brings anything here, especially for someone not familiar with
a functional language.

IMO Nix language isn't actually that hard, I believe the most complexity comes
from nixpkgs and still not adequate documentation of it, so one needs to study
its source code.

~~~
nvarsj
I’m probably biased in that I primarily use Emacs and like lisps. So I find
guix more approachable right out the box. Learning a new language just to use
an OS is quite a big ask and part of the learning hurdle of Nix.

It’s too bad that guix uses old style mailing lists for development though. I
just can’t be bothered setting up myself for that mode of contribution, so
I’ll continue to use NixOS for the indefinite future.

------
Kednicma
I wish I understood how to bring new things to Nix. Like, if I have some
language or framework with a bunch of plugins and modules, and I have the
freedom to bend the framework a bit in order to get it working with Nix, then
what is the best path for doing that? All of the documentation I've read seems
like it's been written by folks who deeply understand not just each different
language, but also some sort of central Nix philosophy.

~~~
juliosueiras
I think one way to look at nix is that it want to act(in good way) the central
source of truth for deterministic package, and one way it goes about it is by
doing the step for both system level packages, and language level packages(for
example, if you approach a nodejs app, you will lock both the nodejs version,
the underlying openssl or other headers lib used by node-gyp, and the
node_module packages itself in nix) and that is one of the main flow of nix,
take a existing project/app/software, and convert it to usable nix packages,
and that work even in edge cases like:

\- app that is binary , so you can't build it from source, but is using
dynamic libraries, then you can use autoPatchelfHook to tell nix to patch the
binary to swap out the libraries to nix's version

\- app that uses a lot of hard coded file system path that you would prefer
not to patch them all out, then you can use buildFHSUserEnv to package/run the
application/package in full FHS-compatible scenario

but the main point is that, nix is extreme in its approach, and the best
approach in my opinion, is to do swapping step by step, ex:

you want to convert a existing project to nix, lets say nodejs

\- you add the main deps in the default.nix (nodejs, yarn, high level utility
needed to build)

\- use sandBox false to allow building the app with yarn/npm in internet
accessible(by default nix uses sandBox which disallow internet inside build
step, which causes issue like npm install not working, etc)

\- confirm working, then start using tool likes yarn2nix, other similar, and
convert the packages itself to a usable set of nix packages

though I do agree that nix have the knowledge bias issue, and alot of my
learning of nix involve me looking at the nixpkg sources itself and sometime
even the nix's code

~~~
throwaway894345
The trouble is that it's not just that nix is opinionated, it's that much of
the complexity is in patterns and conventions that are implemented in nix.
Learning everything about everything about the Nix toolchain is only one third
of the battle; the rest is learning all of the conventions and patterns for
writing Nix expressions, and these conventions and patterns are subject to
variance between target languages. This is made terribly difficult because the
language is dynamically typed and it's almost impossible to know about the
"shape" of any given parameter because there is no way to know where it is
defined in the enormous nixpkgs repo except to grep around and try to find the
place where the caller is invoked, what is passed into it, and trace that back
to an original import statement (and from there to a file on disk and the
corresponding definition). That long tedious process is the hot path for
developing in Nix.

~~~
yjftsjthsd-h
Very much agreed; nix is its own world, which makes it really hard to get
into. I wish someone had written "nix but in python" (or bash, or whatever)
that still used a nix-store equivalent, kept the overall design and the
immutable and reproducible packaging, still connected everything by hash, did
all the hydra-style build infrastructure.. but didn't use nix-the-language,
and made an explicit effort to use more conventional language wherever
reasonably possible. Ideally, it'd even let you write expressions in arbitrary
languages; it should be perfectly possible to say, "here is a directory
containing 'inputs' and 'output' subdirectories based on your declared
dependencies; place any build steps you want in build.sh, so long as they
deterministically populate 'output' from the package directories in 'inputs'"
(and then run the build a few times, without network access, to make sure). I
don't _see_ anything in nix that actually needs nix-the-language, or even a
functional language at all, and I think nix-the-package-manager would be far
more accessible if they'd not tied nix-the-language to everything.

~~~
chpatrick
I think functional languages are a good fit for the problem though. Given some
input, compute a static build plan. It's very rare that you need to do
imperative-style computation for that. What I think Nix really needs is some
kind of static typing, because right now if you make a type error the error
might appear in a completely random location, making it difficult to debug.

~~~
jcranmer
Take this example build file in Mozilla's custom, Python-based build system:
[https://searchfox.org/mozilla-
central/source/gfx/skia/moz.bu...](https://searchfox.org/mozilla-
central/source/gfx/skia/moz.build)

The language is imperative, and the result is fully declarative. A pure
functional description of this logic would worsen understanding instead of
improving it, I believe, because when your conditionals affect multiple output
variables, you have to duplicate the condition in multiple places.

~~~
takeda
Looking at the code, I don't see any advantage of using imperative language
here. All the conditions used there are already available and don't change
during the execution of that code. So the conditionals would be nearly
identical in functional language.

Nix advantage here would be that is lazily evaluated, so there would be an
additional benefit that only conditionals that are used are evaluated.

Functional benefit of Nix would be that Nix would know that a package doesn't
need to be rebuilt if no inputs changed.

Side note Mozilla actually uses Nix internally, it appears that it is used for
Rust and Firefox and most likely other things[1][2]

[1] [https://github.com/mozilla/nixpkgs-
mozilla](https://github.com/mozilla/nixpkgs-mozilla)

[2] [https://github.com/mozilla/release-
services](https://github.com/mozilla/release-services)

~~~
yjftsjthsd-h
> Looking at the code, I don't see any advantage of using imperative language
> here. All the conditions used there are already available and don't change
> during the execution of that code. So the conditionals would be nearly
> identical in functional language.

Yes, except that I can read this and I can't read nix. That's probably based
on background, but more people are familiar with imperative than functional
languages.

> Nix advantage here would be that is lazily evaluated, so there would be an
> additional benefit that only conditionals that are used are evaluated.

Agreed, although that's unlikely to be unique to nix?

> Functional benefit of Nix would be that Nix would know that a package
> doesn't need to be rebuilt if no inputs changed.

As would anything that can compare hashes. Or heck, make(1) can do as much.

~~~
takeda
> As would anything that can compare hashes. Or heck, make(1) can do as much.

Of course, language like Python is Turing Complete so you could implement the
same functionality . You could also add functions that behave and perform
operations lazily.

But you're missing the point though, those are properties that Nix provides
natively that are tuned to what is required for this domain. Because the only
side effect in nix is a derivation, and because language is lazily evaluated
it is made for this purpose.

If you would use for example Python, you would need to write wrappers that
would provide that behavior and it no longer would be Python, it would be some
kind of DSL written in Python at that point and the risk then would be that it
would be very easy to introduce iterative code that's not functional and not
lazily evaluated (kind of like it happens with Chef recipes).

The Nix Language actually is not the problem here, the language is fairly
simple, the biggest difficulty is actually nixpkgs which is huge and poorly
documented. You often have to look at its code to understand what's going on.
If it was written in Python you would have the same issues.

There is one thing that Nix Language could do better, a lot of people wish it
was a typed language, because if it was typed it would be much easier to find
a definitions, and wouldn't require as much of greping the code. But python
again wouldn't help here.

~~~
throwaway894345
Nix is also Turing complete, and Python (to my knowledge) can also run in a
side-effect-free context through various methods (it’s easy enough to enforce
during code review but there are technical solutions as well). There’s also
Starlark which is a sealed, embedded Python-like which is _NOT_ Turing
complete and which can also avoid side effects (evaluating to a derivation, if
you like).

Nix may be simple but it’s unfamiliar, and you’re already asking people to
understand a novel package management system and everything about everything
about their entire dependency tree, and these unknowns are collectively more
confounding than the sum of their parts.

Python would help because it is familiar and gradually typed. That said, I’m
open to any language that satisfies those properties (maybe also “composes
nearly from expressions”).

~~~
takeda
I don't believe Nix is Turing complete, unless you include ability of running
python or bash script.

Regarding the rest of your first paragraph, that's essentially what I said,
you can write side effect free code in python, but it's so easy to introduce
side effects if you're not paying attention.

I'm saying though that nix language isn't the hard part about nix, but perhaps
you're right and it is one extra difficulty that just makes things harder.

But take a look at most o Nix derivations, majority of them end up being just
an attribute set (aka dictionary, map etc in other languages)

Take look at [https://nixos.org](https://nixos.org) page (they changed it
after this submission was posted, and it is better than the old page at
showing what Nix can do)

------
iElectric2
I've started writing tutorials at [https://nix.dev/](https://nix.dev/) to help
people set up their development environment and get up and running quickly.

Disclaimer: the owner of [https://cachix.org](https://cachix.org)

~~~
iElectric2
Feel free to request a tutorial
at[https://github.com/domenkozar/nix.dev/issues](https://github.com/domenkozar/nix.dev/issues)

------
julianeon
I guess the ideal, for me, would be to have a service where I could upload a
Nix file, and then have it generate a server from that. Darklang may be
working with the general idea, but I'd like to see it for Nix too.

~~~
takeda
People mentioned NixOps (I personally think it is weaker part of Nix, but it
is still good for specific use cases)

There's also another option, nixpkgs actually has a functionality to generate
ec2 image, basd on your configuration.nix[1]

You can also generate other images[2]

[1]
[https://github.com/NixOS/nixpkgs/blob/master/nixos/maintaine...](https://github.com/NixOS/nixpkgs/blob/master/nixos/maintainers/scripts/ec2/amazon-
image.nix)

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

edit: I believe you can use [2] even for AWS images, the raw and qcow2 should
work on EC2 as well, the [1] is including some additional settings that make
NixOS work better there, although there's nothing stopping you from adding
these to your own configuration.nix

Also, this is not really a fault of Nix, but in EC2 if you import image it has
to go through their conversion mechansim, which takes about 10 minutes :( A
kind of workaround around it is to have another instance with attached extra
EBS drive, use dd to write raw image on that disk. Then disconnect the EBS,
create a snapshot of it and convert the snapshot to an AMI.

~~~
elbear
I tried to use nixos-generators recently and the experience wa frustrating.
For example, I tried to generate an image in the `do` format (DigitalOcean)
and a few other formats. Every time, the script (`nixos-generate`) finished
running and didn't produce any output.

~~~
takeda
Hmm frankly I did not use nixos-generator before writing this post, and only
generated EC2 images.

But I just tried, and it did work for me. The generated image was provided as
the last line of the output.

It looked like this:

    
    
        Making image hybrid...
        /nix/store/ra02s6nmhfklmsrmhkd960xdqpwghgak-nixos.iso/iso/nixos.iso
    

What OS you run it on? I run this on NixOS 20.03 on VirtualBox, I needed to
have "Enable Nested VT-x/AMD-V" since the process spins a qemu to finalize the
image.

~~~
elbear
When I didn't get any output, I ran it in Ubuntu 18 on a Linode VPS. But I
tried to generate different formats: do, qcow, vmware.

~~~
takeda
Strange that there was no output or even errors.

BTW: I believe NixOS image generation can be run only on NixOS machine,
because it needs to run a VM and that requires some kernel modules to be
loaded. At least I never was able to made it work on OS X.

The nixos-infect code though will turn your Ubuntu installation into NixOS, so
you might try to boot to your Ubuntu machine, convert it to NixOS and I'm
hoping then nixos-generate might start working.

Note though that "do" didn't work either for me, and I didn't look to
investigate why, I figured out that maybe it was because I was running it on
machine on VirtualBox and not DO.

------
PaulDavisThe1st
Just a minor footnote. My interest in Nix is not high and what there is
motivated mostly by the existence of NixOS. Why do I have any interest in
NixOS?

We build and distribute Ardour (a cross-platform open source DAW) in a single
package that runs on every Linux distribution that has libc, libstdc++, and
some version of Xlib.

Every Linux distribution that is, except NixOS. They decided to patch the
runtime linker so that the approach usable on every other Linux distro breaks
there.

This says something about NixOS, and presumably Nix too, though I'm not sure
what.

~~~
pmahoney
Hi Paul, thanks for Ardour.

For anyone curious, this wiki page describes how to package and run some
precompiled binaries on NixOS, particularly the section "The Dynamic Loader":
[https://nixos.wiki/wiki/Packaging/Binaries](https://nixos.wiki/wiki/Packaging/Binaries)

NixOS tries to insist that programs reference only other paths within the nix
store (e.g. /nix/store/9rabxvqbv0vgjmydiv59wkz768b5fmbc-glibc-2.30/lib64/ld-
linux-x86-64.so.2 which is a specific version built by a specific compiler,
rather than /lib64/ld-linux-x86-64.so.2). This is the source of the per-
program isolation that enables all the nifty features of NixOS.

NixOS _does_ make exceptions to that though, for example providing both
/bin/sh and /usr/bin/env at those paths.

~~~
PaulDavisThe1st
The key point here is that we want to package things in a distro-independent
way. In our distro-independent package there is no store and hence on nixOS it
won't run.

Note that the way we do things is not unique - Firefox has been packaged this
way by the Mozilla Foundation for years. We consider ourselves closer to a
"traditional ISV" than merely the provider of source code to the open source
community (though obviously, we play the latter roll too).

We don't have the resources to spend on a nixOS-specific package, nor the
desire. Fortunately, of course, nixOS users can create suitable packages for
nixOS, and I think they are.

It just says something that out of the myriad flavors of Linux, nixOS is the
_only_ one that has broken this rather old concept for packaging software from
ISVs.

But please, carry on! Seems interesting enough.

------
velcrovan
I like the idea of NixOS. It's somewhat hurt by the fact that it's not a
first-class OS at most VPS providers. It also doesn't seem to be quite as
capable as Ansible yet for configuration. If there isn't a provided variable
for the setting you want, there's not a generic way to add a line to a
configuration file, for example. (I might be wrong about this!)

~~~
thequux
Both of these are true, but I find that the second, at least, isn't as much of
a problem as you'd expect. Most modules that configure services give you the
ability to specify complete config files, which you can build whatever higher
level structure you like on top of.

For example, the built-in firewall is fairly basic (at least for running on a
router; it does nearly everything you'd need for most desktop and server
applications). I run NixOS on my router, so I needed something more. So, I
wrote [https://github.com/thequux/nix-zone-
firewall](https://github.com/thequux/nix-zone-firewall) (note: the readme is
slightly out of date, but it does give you the gist of it). First, I built a
way to declaratively put rules in different chains (core.nix), and then I
built a zone-based firewall on top of that. I then have another layer of
configuration options in my router's config (not that repo) to be able to
spread configuration across multiple files.

Even though this was the first significant bit of Nix that I wrote, I still
was able to put the entire thing together in a single evening after work.

------
metta2uall
Thanks. I also found this Cheatsheet from the NixOS Wiki with comparisons to
apt-get to be useful:
[https://nixos.wiki/index.php?title=Cheatsheet&useskin=vector](https://nixos.wiki/index.php?title=Cheatsheet&useskin=vector)

I would also love to see a tutorial for beginners on Linux that covers common
tasks like viewing changelogs, creating a simple package, and pinning multiple
dependencies in an environment.

~~~
1000101
I'm actually aiming to do that in a series of post in the upcoming month(s)...
I've started with a noob-friendly (written by a noob!) introduction and plan
to continue with installer, basic package creation, module creation,
discussing how to do rollback, what are generations etc. etc. ... I did some
presentations on NixOS and these topics so I'd like to distill that into a
short and easy to grasp blog posts @
[https://nixos.online](https://nixos.online) \- feedback is more than welcome!
Maybe I could also include my own cheatsheet, which is refurbished version of
the "official" one, but just for the basic commands in direct comparison to
Debian-like distros.

~~~
aaronchall
A straight-up cheatsheet would be useful.

I didn't find the direct comparison to apt to be useful before installing
nixos, to be honest, but as primarily a `nix-shell --pure` user who just got
nixos installed on my server, I suppose I might revisit it...

