[HN Gopher] A Nix terminology primer by a newcomer
       ___________________________________________________________________
        
       A Nix terminology primer by a newcomer
        
       Author : signa11
       Score  : 107 points
       Date   : 2020-06-01 11:13 UTC (1 days ago)
        
 (HTM) web link (stephank.nl)
 (TXT) w3m dump (stephank.nl)
        
       | carlmr wrote:
       | 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 wrote:
         | _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 wrote:
           | 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.
        
         | tarkin2 wrote:
         | > I also have the feeling that the tutorials start with the
         | details, instead of starting with an overview
         | 
         | Yes. Reading the official docs, or Nix pills, gives exactly
         | this impression.
         | 
         | I've read some good documentation away from the official docs
         | on how to start using the package manager.
         | 
         | But understanding the overview of how to package things
         | yourself is all wood and no trees.
         | 
         | There's so many moving parts in nix that knowing how they all
         | interact, and which ones are important for your task at hand,
         | is a headache.
        
         | tomberek wrote:
         | Got a project or want some guidance? I can help out.
        
           | thibran wrote:
           | Question 1 - What is the correct way to build and install
           | self created derivations? Right now I have a custom fish
           | function:                 function nix-local-build
           | nix-build --no-out-link \           -E '(import <nixpkgs>
           | {}).callPackage ./'$argv[1]' {}'       end
           | 
           | To build and install something I run:                 nix-
           | local-build some.nix       nix-env -i [store-path-from-build]
           | 
           | The .nix file is in the same format as e.g.
           | pkgs/tools/misc/bat/default.nix.
           | 
           | Question 2 - How to include such a derivation into
           | configuration.nix?
        
             | nomurrcy wrote:
             | Overlays can be very helpful for this type of thing.
             | 
             | I have overlays in ~/.config/nixpkgs/overlays.nix (though
             | you do this various ways)
             | 
             | My overlay file has the form:
             | 
             | let my-packages-overlay = self: super: { foo =
             | super.callPackage ./path/to/package.nix {} } in [ my-
             | packages-overlay ]
             | 
             | Then you can just nix-env -iA your-package.
             | 
             | See: https://nixos.wiki/wiki/Overlays
        
               | mason55 wrote:
               | > _Then you can just nix-env -iA your-package._
               | 
               | This is what always gets me stuck. It seems like lots of
               | tutorials assume you're installing packages by hand
               | still. For me, the whole reason I'm using nix is so that
               | I can use the declarative package management.
               | 
               | I get having local dev dependencies on a per-project
               | basis and running a nix shell to make those dependencies
               | available in your development environment.
               | 
               | But it's just confusing to me how many tutorials suggest
               | running nix-env -i to imperatively install a package. Why
               | would I do that instead of taking advantage of the joys
               | of declarative package management?
        
               | nvarsj wrote:
               | I've never used nix-env on NixOS. I really think that
               | command only exists as a bridge for people used to more
               | traditional OS's. I think there is a space for it - if
               | you don't want to spend time building your user
               | configuration declaratively, just install what you need
               | and get going.
        
             | tomberek wrote:
             | Question 1: That is a reasonable way to build and install.
             | I normally structure things like this (https://www.reddit.c
             | om/r/NixOS/comments/8tkllx/standard_proj...) where the
             | Nixpkgs-compatible derivation is in derivation.nix and the
             | default.nix or overlay.nix contains the "callPackage"
             | portion.
             | 
             | Question 2: including such a derivation is easy with
             | overlays or with the method above.                   drv =
             | import ./path-to-derivation.nix;         package =
             | pkgs.callPackage drv {};
             | 
             | or something similar can work. Overlays would be slightly
             | more re-usable, but would take a few more expressions. I'd
             | do that if there are multiple packages you need to
             | introduce; I normally use overlays to manage groups of
             | interdependent packages, a "meta-package".
        
       | julianeon wrote:
       | 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.
        
         | chpatrick wrote:
         | Yep, that's nixops, although it's a command-line application.
        
           | whateveracct wrote:
           | NixOps + the kind of money mainstream projects get would be
           | really nice. Sadly NixOps is a lil rough around the edges. I
           | like using it for my projects already though. I manually
           | provision on DO instead of letting the tool do that.
        
         | ris wrote:
         | You're describing something a little like NixOps, which is
         | something like a cross between nix and terraform.
        
       | Kednicma wrote:
       | 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.
        
         | whateveracct wrote:
         | mkDerivation is a nice hammer to try
        
         | ingenieroariel wrote:
         | Are you stuck with the interface for the user? Based on what I
         | saw with python and postgres the latest and greatest seems to
         | be:
         | 
         | yourthing_custom = yourthing.withPackages(ps: [ps.plugin1
         | ps.plugin2 ] )
         | 
         | Or are you stuck with how to implement it?
        
         | juliosueiras wrote:
         | 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 wrote:
           | 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 wrote:
             | 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 wrote:
               | 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.
        
               | throwaway894345 wrote:
               | I don't think this is any more true for this problem
               | space than other problem spaces. The "pure functional
               | package manager" property doesn't come from the
               | functional expression language, but from the thing that
               | takes the static build plan and executes it. You could
               | make these build plans in Python (or Starlark
               | https://go.starlark.net) very elegantly and with the
               | _massive_ added bonus that they are intelligible to a
               | much broader audience, and Python still allows for a very
               | functional style. The only caveat I would add is that the
               | Nix expression language has really nice support for
               | multiline strings and Python still hasn 't figured that
               | out. Lastly, Python also supports type annotations and
               | even a type checker (although the type checker leaves a
               | lot to be desired, such as basic types or callbacks that
               | take kwargs so it might be better off to implement one's
               | own type checker).
               | 
               | But 100% agreement that Nix needs a type checker!
        
               | chacha2 wrote:
               | > 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
               | 
               | Guix?
        
               | yjftsjthsd-h wrote:
               | I haven't dug in far enough to be confident in this, but
               | I think they basically just did a straight one-to-one
               | replacement nix->guile? Which is certainly better than
               | creating a whole one-off language just for the purpose,
               | but is still tied to the one language, requires you to
               | wrap your head around a hole different mental model and
               | programming environment, and importantly to me, uses a
               | language that I'm not familiar with in a paradigm that I
               | don't frequently touch. I mean, I'm barely a programmer,
               | let alone a LISPer; I can write Arch PKGBUILDs and
               | Alpine's APKBUILDs and BSD port/package Makefiles, but
               | the moment that creating a package requires using any
               | significant amount of a real, non-trivial programming
               | language, complete with local idioms, I'm going to get
               | stuck really quickly. A lot of my frustration with nix is
               | that everything is a special case. There's no way to
               | "configure && make install"; you have to use some special
               | nix module that knows how to handle
               | autoools/cmake/whatever. And I understand why this is
               | really great as long as you're doing something expected,
               | but the first package I tried to write didn't fit into
               | any of the obvious patterns so I was stuck in the deep
               | end with no obvious way to just write the three shell
               | commands that I needed to actually build the package.
        
       | velcrovan wrote:
       | 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!)
        
         | chpatrick wrote:
         | You're right in general, but most nixos modules have an
         | `extraConfig` field where you can put whatever you want.
        
         | thequux wrote:
         | 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 (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.
        
       | seddona wrote:
       | 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.
        
       ___________________________________________________________________
       (page generated 2020-06-02 23:00 UTC)