So instead of commenting inside of nix files, you put nix files into .org documents and collate them so you can make your nix files an OS and a website and a zettelkasten-looking set of linked annotated nodes.
Yup! And writing it in Org allows me to structure the configuration any way I like. It makes it a whole lot easier to group things that belong together close to each other, and I never have to fight the Nix language to do so. I can also generate easily browsable, rich documentation that explains what’s what and why, which helps me tremendously, because a year after I installed and configured something, I will not remember how and why I did it that way, so my own documentation will help me remember.
Generating code from docs (rather than the other way around) also means that I’m much more likely to document things, because the documentation part is the more important part. It… kinda forces a different mindset on me. And, like I said, this allows me to structure the configuration in a way that makes sense to me, and I am not constrained by the limitations of the Nix language. I can skip a tremendous amount of boilerplate this way, because I don’t need to use NixOS modules, repeating the same wrapping for each and every one of them. Also feels way more natural, to be honest.
You have home on tmpfs. Isn’t that volatile? Where do you put your data/pictures/random git projects? Build outputs? How’s your RAM? (Sorry if I’m missing something obv)
It is volatile, yes, in the sense that if I reboot, it’s lost. I am using Impermanence, for both /home
and /
. The idea here is that anything worth saving, will be recorded in the configuration, and will be stored on a persistent location, and will get bind mounted or symlinked. So data, pictures, source code, etc, live on an SSD, and they get symlinked into my home. For example, the various XDG userdirs (~/Downloads
, etc), I configured them to live under ~/data
, and that dir lives on persistent storage and gets symlinked back.
My root and /home
are both set to 128Mb, intentionally small, so that if anything starts putting random stuff there, it will run out of space very fast, and start crashing and complaining loudly, and I’ll know that I need to take care of it: either by moving the data to persistent storage, or asking whatever is putting stuff there to stop doing that. My /tmp
(where temporary builds end up) is 2Gb, and sometimes I need to remount it at 10gb (hi nerdfonts
!), but most of the time, 2g is more than enough.
I have 32Gb RAM, but only ~2.5g is used for tmpfs purposes (2g of it on /tmp
itself), and most of the time, the majority of that is unused and as such, available for other things. My wife’s laptop with 16Gb RAM uses a similar setup, with 512mb for /tmp
, and that works just as fine.
I do have 64Gb of swap on a dedicated SSD, though, and that helps a lot. I currently have 3GB ram free, and 37G of swap used, but don’t feel any issues with responsiveness. I don’t even know what’s using my swap! Everything feels snappy and responsive enough.
What’s your bootup like?
A few seconds from poweron to logging in. By far the slowest part of it is the computer waiting for me to enter my password.
❯ systemd-analyze
Startup finished in 8.667s (kernel) + 29.308s (userspace) = 37.975s
graphical.target reached after 29.307s in userspace.
Looking at systemd-analyze blame
and systemd-analyze critical-path
, most of that userspace time is due to waiting for the network to come online (18s), and for docker to start up (7s). Most of that is done parallel, though. Boot to gdm is waaay faster than that.
Another commenter mentioned difficulties in setting up specialized tools w/o containerizing, and another mentioned that containers still have issues. Have you run into a sitch where you needed to workaround such a problem? (e.g. something in wine, or something that needs FHS-wrangling)
I haven’t run into any issues with containers, and I’m using a handful of them. docker, podman, flatpak all work fine out of the box (after setting up permanent storage for their data, so they don’t try to pull 10gb containers into my 128mb root filesystem :D). Wine… I’m using Wine via Lutris to play Diablo IV, and it has worked without issues so far out of the box, I didn’t have to fight to make it work.
I did run into a few problems with some stuff. AppImages for example require running them with appimage-run
, but you can easily set up binfmt_misc
to automatically do that for you, so you can continue your curl https://example.com/dl/Example.AppImage -o Example.AppImage && chmod +x Example.AppImage && ./Example.AppImage
practices after that.
There’s also cases where downloaded binaries don’t work out of the box, because they can’t find the dynamic linker. I… usually don’t download random third party binaries, so I don’t often run into this problem. The one case where I did, is Arduino tooling. I have a handy script in my (arduino-powered) keyboard firmware to patch those with patchelf
. But if need be, there’s buildFHSEnv
, which allows us to build a derivation that simulates an FHS environment for the software being packaged. So far, I did not need to resort to that. Come to think of it… using buildFHSEnv
would likely be simpler for my keyboard firmware than the patching. I might play with that next time I’m touching that repo.
I’m one of those crazy people with
/
and/home
on tmpfs. Setting that up is very easy with Impermanence, but it does require some care and self control. That is precisely the reason I set it up: I have no self control, and need the OS to force my hand. Without impermanence, my root and home fills up with garbage fast. I tend to try and play with a lotof things, and I abandon most of them. With Impermanence, I don’t need to clean up after myself: I delete the git checkout, and all state, cache and whatnit the software littered around my system will be gone on reboot.In short, Impermanence makes my system have that freshly installed, clean and snappy feeling.
The whole thing sounds scarier and more complicated than it really is.