NireBryce

reality is the battlefield

the first line goes in Cohost embeds

🐥 I am not embroiled in any legal battle
🐦 other than battles that are legal 🎮

I speak to the universe and it speaks back, in it's own way.

mastodon

email: contact at breadthcharge dot net

I live on the northeast coast of the US.

'non-functional programmer'. 'far left'.

conceptual midwife.

https://cohost.org/NireBryce/post/4929459-here-s-my-five-minut

If you can see the "show contact info" dropdown below, I follow you. If you want me to, ask and I'll think about it.


yes the documentation is terrible, yes you will have to pretzel your brain into overthinking it until it clicks and you finally understand.


HOWEVER

once you're there it enables fearless exploration because if you break something, rolling back to a previous config is a simple as grabbing the previous working commit off github, even if you somehow delete all your previous nixOS generations.

the thing that sold me on nixos is I basically never need to learn another syntax to interact with my system, and with rnix-lsp and the others I can have partial LSP/IDE support.

need to do a systemd thing? look up some people's implementations of it, and just do that with the nix syntax I already know.

need to do kernel patches?

&c &c. All the little things I do once every 6 months and will never remember the syntax of.

thats it, that's the post. Every problem I have takes four times as long to fix, and then I never have to fix it again, on any install going foward.

YOU DONT NEED TO LEARN THE NIX LANGUAGE. IGNORE THOSE PARTS OF EVERY BOOK. YOU WILL GET BORED. YOU WILL GET CONFUSED IN WAYS THAT HURT YOU LATER. YOU WILL TAKE A YEAR TO COME BACK.

skip nix pills. ignore the language-teaching parts of the manual. you need to know maybe the types. go back to those parts when trying to figure out specific parts of what you're doing. you literally do not need it to do nixos. It's imo bad that everyone is so insistent on this for how beneficial the OS can be.

ignore it. skip the chapter. you don't need to know anything but the data structures and boilerplate. I mean it. Go back and learn it later. Use the nix manual and nix pills for reference only.

and remember: the nix manual is not the nixos manual. nix is the language it's built with. learn nixos

anyway: instead of half remembering what I did to every machine over it's lifetime whenever I want to install/reinstall an OS to it, I just have a set of config files that build machines.

it may not be pretty, but this is Linux on the Desktop in it's childhood.

which is funny because I hear it's used more as a server OS.

want to get steam working? just add it to your config lol simple as.

kde plasma 5 to kde plasma 6? change one character in the config (and then maybe nix-collect-garbage (if you know what you are doing) because the packages changed their source)

I can provide limited tech support, but do all of this at your own risk.

Notes and Tips (AKA: the actual guide) :

  • github code search is your friend. it's at the top of github, unfortunately you need to be logged in. Click "Code" instead of "repo" in the sidebar. Search for the option you're looking for. Harvest usage examples until it works.
  • ignore that it's a language for now. skim the datastructures/types section and then just treat them like you would configs until you need to know more: horizon-zero-dawn useful parts from other people's dotfiles on github, then figure out how they work. The error messages are bad. I know. That's been a problem since 2013.
  • Home-Manager is like NixOS but for your home directory
  • for a simple introduction to Home-Manager, try https://getfleek.dev
    • you WILL outgrow this if you run mixed-type machines. That's good. It lets you gradually learn home-manager. You can put custom stuff in `$HOME/.local/share/fleek//custom.nix
  • home manager lets you get used to the NixOS Experience without having to take the leap
  • when you do take the leap, build out a booting config on a VM, then boot a live ISO and install via the graphical installer (unless you want like btrfs) and then bootstrap from the package you already wrote.

if you use nix flakes, you MUST have your configs tracked by git in a repo, and git add . before it will show up when you nixos-rebuild switch --flake .#<hostname>. This is a common gotcha, and fails 'silently' (because it doesn't know your files need to exist)

nix-flakes ignore things that aren't tracked by git.

Guides in no particular order except the first one:

Resources:

Syntax that tripped me up:

  • imports = [ ./path/to/config/file.nix ] is equivalent to 'sourcing' in bash/zsh configs, it pulls from other places
    • you can specify folders, ./path/to/config/folder, and it will read that folder's default.nix if it exists. default.nix can then import specific things from that folder in it's imports section, allowing you to easily modularize
  • Many scripts are put between '' "double-single-quotes" blocks
    • that is, '' [...] '';.
    • The other place double-singles come up is escaping shell variable expansion, $HOME needs to be written as ''$HOME. Note that this is an escape character, and does not need closing tags.
  • Most lines need to end in semicolons, sorry.
  • If you're familiar with JSON, lists and attribute sets are roughly equivalent to JSON lists and JSON objects
  • you can expand options like so:
# in nixos/_common/_impermanence.nix
{ config, pkgs, impermanence, ... }:
{
  ...
  filesystems."/".options = [ "compress=zstd" "noatime" ];
  filesystems."/home".options = [ "compress=zstd" ];
  ...
}

can become:

{ config, pkgs, impermanence, ... }:
{
  ...
  filesystems = {
    "/".options = [ "compress=zstd" "noatime" ];
    "/home".options = [ "compress=zstd" ];
  };
}

BECAUSE THE FILE IS BUILT, IT IS EVALUATED NEARLY SIMULTANEOUSLY IN PRACTICE.

load order largely doesn't matter spatially, so you can, say, install a package in the same module you configure it in, if you want. at that point you're already half way to a writing a custom package yourself, and you didn't do that much extra work.

The Documentation

"but where's the documentation?"

in terms of being able to learn it, basically nowhere. All of it is written for people who already mostly get both nix and linux.

read the source code instead. not of nix, of packages. treat the description fields as "comments" to the options you're trying to figure out.

and write things. ride the compiler errors until it works and you understand the differences between each of the types/"data structures"

these sound annoying and hard because you're thinking it's like C but no: all that shit is already done for you, the secret here is that every action that you will reasonably do for nixOS is functionally equivalent to having a very long .zshrc/.vimrc or whatever.

but the same syntax across every aspect. you can do the translation as you go and eventually use nix to configure vim, zsh, systemd, you window manager, and low level OS stuff with the same language. as if it was a vim/zsh config.

if it helps, you can mostly just ignore all the parts that say it's a functional language too. Practically speaking you can think of = { as { in most other languages and figure out the details yourself. good luck.


You must log in to comment.

in reply to @NireBryce's post:

yours and others' posts on this continually make me bounce between "running nixOS sounds like signing myself up for hell and I'm already buried in personal tech debt" and ".... yes AND maybe I would eventually have a stable if not actually GOOD personal setup at the end of the hell"

yeah but github codesearch didn't really work back then which is a big part of why it's a now thing.

but yes its also sort of like converting to judaism in that I needed to throw myself at a learning cliff three times before it worked

--aggressive yes, but WOW the things we had to do to make it work

we were particularly surprised that it actually saved us anything, the manpage is very skeptical about the idea it will have much effect. apparently something like the nixpkgs repo is the scenario where repacking old packs does matter.

but, we found a bug

it reliably crashed, every time. hard segfault (probably exploitable, but the victim would have to spend several hours voluntarily running git gc --aggressive). we thought it might be running out of RAM but after several hours of measurement, that turned out not to be the issue.

we guessed that it might be a race condition, so we tried to tell it to use a single thread. unfortunately none of the threading options apply to that command (we thought they might work but be undocumented, but nope).

so we had to figure out how to use kernel namespacing to restrict it to a single core. can't remember if cpulimit was enough or if we had to mess in /sys by hand, we documented our steps on a thread...

that was all just on the HOPE that it would fix things. but! it did! the run that worked took about four hours of wall-clock time as we recall. and now we hopefully won't have to do it again for many years, as long as we create all our new repos by cloning from the ones we've already done this to.