diff options
| author | Xe <me@christine.website> | 2021-11-10 12:26:25 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-10 12:26:25 -0500 |
| commit | 48a569c8ed6486f2238dde0307e7b32dce8ef2d6 (patch) | |
| tree | f573203db67b0d38a89e785d3361f843c7d029fb /talks | |
| parent | 65bd9b4c20859dd5f614446bb0c593bdb9c5e780 (diff) | |
| download | xesite-48a569c8ed6486f2238dde0307e7b32dce8ef2d6.tar.xz xesite-48a569c8ed6486f2238dde0307e7b32dce8ef2d6.zip | |
talks: add Nix and NixOS Close to Perfect talk (#411)
For PackagingCon 2021.
Signed-off-by: Xe <me@christine.website>
Diffstat (limited to 'talks')
| -rw-r--r-- | talks/nixos-pain-2021-11-10.markdown | 402 |
1 files changed, 402 insertions, 0 deletions
diff --git a/talks/nixos-pain-2021-11-10.markdown b/talks/nixos-pain-2021-11-10.markdown new file mode 100644 index 0000000..34e0e8d --- /dev/null +++ b/talks/nixos-pain-2021-11-10.markdown @@ -0,0 +1,402 @@ +--- +title: How Nix and NixOS Get So Close to Perfect +date: 2021-11-10 +slides_link: /static/talks/nixos-pain.pdf +tags: + - nix + - nixos + - docker + - packagingcon +--- + +# How Nix and NixOS Get So Close to Perfect + +## Author's Note + +Since my [last +talk](https://christine.website/talks/systemd-the-good-parts-2021-05-16) was so +well-recieved, I thought I'd do this talk on NixOS much in the same way as I did +in the systemd one. I have published this talk as a slide deck, a transcript +(thanks to massaged YouTube auto-captions) and finally as a YouTube recording of +the talk itself. I submitted this as a prerecorded talk to +[PackagingCon](https://packaging-con.org). + +This format of talk takes so long to put together, but I feel the result is +worth it. I get to use skills that I rarely get to pull out of my hat. Enjoy! + +## YouTube Embed + +<center> +<iframe width="800" height="450" src="https://www.youtube.com/embed/qjq2wVEpSsA" +title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; +clipboard-write; encrypted-media; gyroscope; picture-in-picture" +allowfullscreen></iframe> +</center> + +YouTube link: [https://youtu.be/qjq2wVEpSsA](https://youtu.be/qjq2wVEpSsA) + +## Transcript + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/001.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/001.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/001.d.png" alt=""> + </picture> +</center> + +Hi, my name is Xe. Today I'm going to talk about Nix and NixOS. This is my +favorite Linux distribution and it's one of my favorite tools for building +software. However it has a lot of rough edges that make it hard to learn and +make it just not as perfect as it could be. In this talk I'm going to go over a +lot of what makes it great and what I'd love to see make it even better. + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/002.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/002.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/002.d.png" alt=""> + </picture> +</center> + +As I said my name is Xe. I write a lot about Nix and NixOS and use it a lot +personally and soon professionally. As a disclaimer, this presentation may +contain opinions. These opinions are my own and not necessarily the opinion of +my employer. I do not intend ill will to any people or their work in this +presentation, and I want this to be better because I am passionate about these +tools. I believe that this is the best and obvious choice to do things. + +The qr code on the slide links to my website christine.website. I'll have the +talk on the website within the same day the presentation you're watching right +now. + +### Why NixOS is Great + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/003.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/003.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/003.d.png" alt=""> + </picture> +</center> + +Let's start with why NixOS is great. NixOS is great because it lets you pick +from cookie cutter templates to make a server do exactly what you want. It +builds on the shoulders of giants to make it easy and effective to make your +servers built purpose. As an example here's a little NixOS module that enables +nginx and postgres on a server. + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/004.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/004.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/004.d.png" alt=""> + </picture> +</center> + +That's it! This modularity also extends to your own custom modules. I've done +some write-ups on how to write these custom modules but here's an example for my +gemini server. + +Finally, one of the best parts of NixOS is that it makes it hard to do something +the wrong way. You can't just hack up a systemd unit on the fly. You need to do +it the right way in configuration management. This makes it easier for you to +ensure servers aren't being tampered with without going through a review process +and so you can go back to a project in six months and still have some idea on +how it's supposed to run on a computer. + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/006.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/006.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/006.d.png" alt=""> + </picture> +</center> + +However one of the biggest things in my book is the fact that NixOS lets you +undo configuration changes. Worst case you might need to reboot into an older +config; but in general if you mess something up you can go back. This is a +lifesaver, especially when you mess up network configuration. + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/007.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/007.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/007.d.png" alt=""> + </picture> +</center> + +So this sounds great and all but you might be thinking "there's a catch, right?" +There is a catch, it is hard to learn. The tooling and documentation are not the +best and they are the most important parts of the stack that you deal with when +you're learning it. + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/008.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/008.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/008.d.png" alt=""> + </picture> +</center> + +This is a little comic showing a rocket-powered wagon which is kind of what +NixOS can feel like at times. One of the bigger tooling issues is somewhat +technical somewhat social right now the Nix universe is in the middle of +switching to a new hermetic view of the world they call "flakes". Flakes has a +lot of differences between classic Nix and it makes a lot of techniques and +configuration non-transferable between the two. It has effectively soft split +the community between people that use flakes and people that don't use flakes. I +personally don't use flakes because I haven't seen good arguments as for why I +should. + +Nix the language can look a bit like a combination of haskell and bash in ways +that are kind of deceiving to people that don't have solid experience with +haskell or other functional programming languages. This is a little bit of code +that breaks a host colon porn thing into just the port number so that you can +add it to a firewall rule. Additionally it also checks if you have tls enabled +with the http certification for Let's Encrypt and adds port 80 for that. If you +aren't really familiar with Haskell or other functional languages (and without +the 14 plus lines of comments explaining what's going on from the place i pulled +this from), it's going to be difficult to understand what's going on. + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/010.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/010.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/010.d.png" alt=""> + </picture> +</center> + +Another annoying part is that Nix the package manager, Nix the language and +NixOS the operating system all have very similar names and kind of semantically +override. I have created a handy diagram that maps out the relationships between +them and here it is: + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/012.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/012.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/012.d.png" alt=""> + </picture> +</center> + +Nix the language is not nix the package manager, even though Nix the package +manager uses Nix the language in order to do things. NixOS the os is not Nix the +package manager even though it uses Nix the package manager to manage packages. +NixOS the os is not Nix the language even though NixOS uses Nix to configure +itself. The overall relationship is similar to the holy trinity or javascript +equality rules and can be a bit deceiving to learn at first. + +Another paper cut is that Nix does have a REPL so that you can hack up things +quickly and so you can get to learn the language a bit better. However, the REPL +can take different syntax than you can put in files. If I want to declare a +variable like foo = "bar" and then use it somewhere in the REPL, I have to do +foo = "bar" without a semicolon and without a let. That can be very annoying at +first because you can hack up something in a REPL and then your instinct is to +go and paste it into a file; but you need to edit it a little bit and it's not +entirely obvious at first. + +NixOS has modules to configure itself, however these modules are only as +flexible as they are written to be. If someone doesn't allow you to do a certain +type of configuration to a module to a program that's behind an NixOS module, +you just can't do it without fixing the module. These sort of make them more +like templates instead of functions for reaching a desired system state. +However, this will get you most of the way there (but when you get into very +complicated setups it can get challenging). + +Adding on to this, most of the modules in the standard set that are shipped with +NixOS are not documented in the NixOS manual, including nginx. There's a search +site that lets you query the list of options in the standard set, however if +you're not entirely sure what you're doing there's not always a good template to +start from when your needs change beyond what the NixOS module is doing. You can +actually monkey patch it, however you have to monkey patch the side effects of +the modules rather than monkey patching the module itself. As an example of an +obscure module let's look at WeeChat. WeeChat is an irc client (it's the one I +use) and NixOS has the ability to manage WeeChat for you. + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/016.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/016.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/016.d.png" alt=""> + </picture> +</center> + +This is all the documentation for the WeeChat module. All of these things expand +out and have more detail, but these are all the settings that you have directly. +Another thing about this module is that it's great for running one instance of +Weechat, but if you want to run multiple copies of it or like a community shell +box you either need to write your own NixOS module that allows you to do that or +use NixOS containers to do that. At that point why not use Docker? + +Another huge paper cut is with disclosure and vulnerability detection for +security reasons. Something important for both standard production and +certification is the ability to answer the question "how do I know a server is +patched against a certain vulnerability?" There are a lot of inherent advantages +to NixOS that would make this a lot easier however there is not really a good +way to do it. There are not regular communications about security +vulnerabilities. This can make certification difficult. + +Another annoying thing is backports. There are no hard rules on what is to be +backported and what is not to be backported which means that packages in stable +branches likely will bitrot from what the upstream intended. Most of the time +you can run NixOS unstable to work around this, but it may not be the best idea +to run the unstable branch in production. + +Also if you want to configure PAM to do something special such as send a slack +message to some channel whenever someone logs into a machine or runs a sudo +command and that option is not already in the pam options in nixpkgs, you're +basically doomed because pam is not very configurable on NixOS. The PAM modules +offer you the ability to enable things like TOTP two factor auth, but that's +about it. + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/022.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/022.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/022.d.png" alt=""> + </picture> +</center> + +Another annoyance comes when you're trying to deploy software on a production +cluster using Nix itself. There's not really a good tool in the standard Nix +tool set for this but there are tools like NixOps and Morph. These allow you to +describe the state of your entire fleet of computers with the same NixOS module +syntax that you use for local machines. However the documentation for these is +lacking. NixOps does have a fairly decent manual and the documentation for Morph +is a bunch of example configuration files. I have a little screenshot of part of +my morph configuration for my home lab. This manages the NixOS machine under my +desk. There are other options than using NixOps and Morph however these are the +more Nix native approaches to do it. + +Because NixOps and Morph aren't very documented it makes it an annoying catch-22 +situation where learning NixOps and Morph requires you to already know how +NixOps and Morph work, which can make it hard to get started from scratch. This +is part of the reason why I make all of my NixOS configs public on GitHub. It +lets people have something to go off of when they're trying to figure out how to +do more complicated things. Without publishing my configs on GitHub I would be +afraid that people would get incredibly lost (like I was when i was trying to +figure it all out). + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/024.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/024.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/024.d.png" alt=""> + </picture> +</center> + +As an example of things that just got me totally lost let's talk about keys. +NixOps and Morph use the term "key" where other ecosystems would use the term +"secret". They basically allow you to have values that aren't managed in your +git repo for things like database credentials, AWS credentials or other api +keys. Normally you want to have things so that this service (for example, this +service that I wrote for myself called mi) depends on the keys for it being +present. In NixOps and Morph what you're supposed to do is you're supposed to +make a secret for that. It will create a systemd service and then you sequence +the systemd job to start after the key. However, the documentation doesn't +really make it clear on how to do this; and I had to figure this out by +searching GitHub for NixOS code, praying someone already figured it out and +made it open source. + +Another annoyance is that you can't pull values from other machines in your +cluster. If you have a VPN with a dynamic ip address and you want to pull that +ip address to use in various bits of configuration, You're going to have to hard +code it somewhere; which means that it's a bit more difficult to do things +dynamically. In comparison when using something like Ansible it is trivial to +pull this information off of a machine with its fact system. + +### A Vision of A Better Place + +Finally let's talk about what I think could make all of this better easier to +learn (and a much more obvious choice for production). These are my ideas. They +may not entirely work in the real world but in an ideal world this is what I'd +love to see. + +First of all I would love to see the documentation being the strongest part of +the NixOS ecosystem. Documentation is the difference between understanding +something and not understanding something. You generally have to understand +something to be able to use it productively. In general, the standard +documentation should cover how to get started, what you can do, and detailed +documentation on every single thing that ships with NixOS by default. There +should be no module in the library of modules without documentation on how to +use it and an example or two of where you'd use some of the weirder options. + + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/028.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/028.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/028.d.png" alt=""> + </picture> +</center> + +Error messages are also critical for understanding what's going on. Here is an +example of an error message that i have encountered in Nix and NixOS a lot of +times that just has utterly baffled me every time. No adding the --show-trace +flag does not show more detailed location information. In this case I got it by +sequencing a package import in the wrong place in a way that didn't seem obvious +to me, but without better error messages you you just have no idea what's going +on. + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/029.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/029.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/029.d.png" alt=""> + </picture> +</center> + +Let's consider some examples of better error messages I've seen around in other +projects. Here's Rest and Elm. In this case Rust is saying that "I don't know +what you're doing with this value, you're trying to return something from an if +statement but then you're just totally ignoring it" and in Elm List.nap is used +in place of List.map. In both of them the compiler tries to work with you to +help you figure out what went wrong. Another great thing about what Rust does is +that it has error codes that you can google for when you have something going +wrong so that you can more easily understand what you're doing wrong and how to +learn how to not do it in the future. + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/030.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/030.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/030.d.png" alt=""> + </picture> +</center> + +This is being worked on, here's an example of what the better error messages +look like. I just wish this was here sooner. + +[NOTE: this was true at the time of recording (late October 2021), but it has +since landed with Nix 2.4. Good work, Nix team!](conversation://Mara/hacker) + +Another way that things could get a lot better is by taking advantage of +language specific package managers to automatically figure out what to do +instead of having to fight them against what they are doing. There are tools +that automate this but ideally I'd like to see this just automatically happen +using import from derivation or something like that. As it is right now +packaging things like Go, Node and other things are really iterative and +annoyingly non-trivial. + +Maybe it would be better to have modules act kind of more like functions than +templates. It would be nice to have modules return something that you can splice +into your configuration instead of the modules being enabling something into +your configuration so that you can manually monkey patch things and run multiple +instances of a service if you wanted to. You can work around this (like I +mentioned) but it would be better if this was a native solution. + +<center> + <picture> + <source srcset="/static/talks/nixos-pain/033.d.avif" type="image/avif"> + <source srcset="/static/talks/nixos-pain/033.d.webp" type="image/webp"> + <img src="/static/talks/nixos-pain/033.d.png" alt=""> + </picture> +</center> + +And that about wraps it up. NixOS is actually pretty great it's just really +frustrating to get started with. I really wish it was easier but right now it +just isn't. If you have any questions about this talk please feel free to ping +me on twitter or some contact method on my website. I love answering these +questions. I'll stick around in the chat for a bit and answer questions if you +want to ask them there. Thank you, stay safe and be well. |
