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:
- the guide I use for making my / overwrite itself on boot (script currently broken, I need to ask the author)
- WARN: advanced, also doesn't work. But a great way to learn flakes by example. https://guekka.github.io/nixos-server-1/
- similar guide that goes over doing it with LUKS encryption https://mt-caret.github.io/blog/posts/2020-06-29-optin-state.html, read the above guide for the updated script that doesn't use postDeviceCommands or whatever since that can cause data loss, except the fix doesn't actually work and I need to figure out why.
- xenofem on patching https://cohost.org/xenofem/post/4946953-another-thing-i-real
Resources:
- the nixos manual https://nixos.org/manual/nixos/stable/#sec-installation
- unofficial nix flake book: https://nixos-and-flakes.thiscute.world/
- nixos package / option search (toggle option search at the top) https://search.nixos.org/packages
- home manager option search: https://mipmip.github.io/home-manager-option-search/
- nix pills if you want to learn nix-the-language fast.
- viv's post on escape hatches, like using flatpak for apps you don't want to go through the hassle of nix with if they aren't pre-packaged https://cohost.org/viv/post/4931843-some-of-my-favorite
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'simportssection, allowing you to easily modularize
- you can specify folders,
- Many scripts are put between
''"double-single-quotes" blocks- that is,
'' [...] '';. - The other place double-singles come up is escaping shell variable expansion,
$HOMEneeds to be written as''$HOME. Note that this is an escape character, and does not need closing tags.
- that is,
- 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.
