How I like to install NixOS (declaratively)

  • I've been trying to get a reasonable Linux-based audio setup on my desktop. Linux audio is a confusing disaster and I'd basically given up on Ubuntu, having run through so many debugging steps I had no idea how my system even got to this state.

    I figured what the hell, let's try NixOS and see if I can set it up declaratively. At least that way if it fails, I have documentation about what exactly is failing.

    I discovered the audio packages I needed easily enough. But things weren't great, there was occasional noticeable lag on the mic and midi devices. Ok, let's try to compile a realtime linux kernel... Wait there's an entire project dedicated to Nix audio setup! (https://github.com/musnix/musnix) After a few minutes integrating with my config, and about an hour to compile the kernel. Rebooted and bam. It's almost like working with analog in terms of perceivable lag.

    I know this says more about Musnix than Nix, but I think it highlights the advantages of configuring your system with a real programming language. All the "audio stuff" was able to fit behind a well-designed abstraction barrier.

    Going back to a "do this, now do this" tutorial feels like the dark ages. The only thing keeping me from going all-in on Nix is that it's package management strategy starts bleeding into your software project's dependency management. This is a huge problem IMO, I can't run C/C++ or Python projects the "old way" and no one is willing to upend their build system and lock it into nix. Some languages work great and allow a clean barrier between system<>app. I use Clojure, Rust, Gleam, Go, Lua on nix without any issues, it does seem to be the C/C++ ecosystem and dynamic linked shared libraries that are the problem.

  • I have recently adopted Nix and NixOS and it's been truly fantastic. It does have a really harsh learning curve though. Big downsides, but for me the upsides are so huge that it's worth it.

    I had been incrementally building this complex workflow using mkosi. At some point I sat down with a pencil and asked myself "ok, what am I building here, what's the ideal endgame?" I sketched out the system I wanted and pondered it for a bit... And then went "wait, have I just described NixOS?" And yeah basically it's exactly what I wanted and more.

    Funnily enough, this article is _exactly_ what I need as I haven't exactly figured out the best way to install NixOS on a totally blank machine. (So far I have been muddling through what's described in the "Manual installation" section and, yeah it sucks). The exception is for Raspberry Pi where it's straightforward to just build an SD card image from a flake.

    I had _guessed_ that something like the "Building your own installer" section would work, but because of the nature of Nix I never really feel 100% confident that something is gonna work as I hope until I physically try it. Usually it does. But still, this is a very big downside of Nix!

  • I gave it a go twice and i just couldn't stick to using it. So many annoying little problems in general that i gave up. I configured system in the end but it was still annoying. I even had conflicts with some pkgs like Smile emoji picker and Gearlever, ok you can say: why do you need that? but lets say i do. And i got a conflict and couldn't install them together. I thought the whole point of nix is to have independent pkgs but i get in practice a conflict which now i have to figure out how to solve and there is no info online. There are many bugs and bad abstractions. I can use nix for local dev (devshells) though.

    With Ansible i get repeatable setup of my whole system. I can setup and install every program, configure it (dotfiles), setup services automatically and users and i have vault to easily encrypt secrets end embed them or template things out which is much nicer than using nix. I run a playbook and set everything up in 15 mins and the most "annoying" thing i have to do is basically log into few websites that i use daily.

  • Not to criticize the article, which is very well written, just some extra info:

    It seems for the author, the custom installer is mainly used for accepting user SSH public key, terminfo, and maybe also locale.

    Almost none of the packages the author listed get used, including zsh. Since NixOS is installed via nixos-anywhere, it runs a bash script to do everything, and all the script's dependencies will be pulled by nix.

    For people who don't want to build a custom installer, or their cloud environment doesn't allow one, you can simply host a script somewhere and download and run it on the remote machine to add your SSH public key and other customizations, including partitioning the disk.

    Note that the author used disko to partition the disk declaratively. Disko won't work for a machine with very limited ram, because disko runs in the installer, and needs to install tools to the ram to do the partition.

    I wrote a nix configuration library[1] that also does NixOS installation (uses nixes-anywhere under the hood), where you can choose between using disko, a default script[2] that handles 90% of the use cases (using only the default tools available on a vanilla NixOS installer, so nothing gets installed to the ram), or your own script.

    [1] https://github.com/hgl/nixverse

    [2] https://github.com/hgl/nixverse/blob/main/load/partitionScri...

  • One of the nixos-anywhere maintainer here. I am currently debugging the digitalocean cloud-init for the nixos-anywhere-examples repository. Has someone contact to digitalocean regarding that? There is a shebang that could be easily fixed to run on NixOS (/var/lib/cloud/scripts/per-instance/machine_id.sh).

  • For Ubuntu it’s possible to use debootstrap to install to an external drive directly. Once you’ve done that, you can chroot into the new drive, fix up a few things that aren’t handled (mounts, locale), then install any software you want on top. Even stuff like installing new kernel/drivers works. Running docker in the chroot also works, if you copy the setup used in docker-in-docker. I wonder if a similar setup is usable here.

    Side note wrt tailscale - you should be able to auth without manual registration. Two choices: 1. Make a reusable key that grants the ACL you want to give, store it somewhere secure on your provisioner, then “ssh user@tag sudo tailscale up —-auth-key=$key” to deploy. 2. Make a new tag for “disabled-machine” or similar, locked down with no access. Embed that key in your ISO and use whatever mechanism you have to start it up on boot.

    Either way you no longer have to copy paste the setup link to your browser, and the machine always starts off with the ACL tags you want (setting an ACL tag automatically disables expiration btw - no need to do both).

    2 is likely tricky to do securely, so take care. :)

  • I just "lustrated" [0] my Debian Stable machine onto NixOS on Friday, and it's gone surprisingly well! It sounds silly, but I installed this way because I didn't want to figure out how to mount my LVM + LUKS encrypted partition on the live USB.

    What is lustrating? Basically, you run the NixOS installation tools on an existing Linux installation (install the tools with the Nix package manager). The installer wipes out anything on / that doesn't belong, with a few exceptions, including /home and anything listed in /etc/NIXOS_LUSTRATE, a file you create as part of the installation steps.

    [0]: https://nixos.org/manual/nixos/stable/#sec-installing-from-o...

  • I was always surprised that NixOS doesn't have a better story there, the main install instructions are to do manual partitioning, generate a config, edit it, etc. What I had expected at first would be that you'd write the config first and then deploy it, like in the article. But even with the method presented here you have the imperative step of running nixos-anywhere. Having something like the ignition system of Fedora CoreOS where you'd point at an existing config and it would install everything would make more sense IMO. Or pre build an iso which installs itself.

  • I want to like NixOS I just hate the language — idk maybe I’m in the minority. Give me a functional language like F# or some better DSL that builds a DAG and then you’re golden.

  • You know, I don't see why Arch and other distros couldn't have a declarative abstraction layer. You don't hsve to go full Nix or GUIX just to hsve that.

  • Every time I try to use NixOS I start off excited about all the benefits it can provide, but it always ends up frustrating me in some way and I'm reminded of why distributions exist in the first place. I don't want to have to dig into a config file for every little aspect of my OS to be in working order and then worry about having some hackey workaround when something has issues due to the lack of adherence to the FHS.

  • Here's my own repo with a very similar setup! https://github.com/mjmaurer/infra

    I build the ISO via a Github action as well. The biggest pain point is adding / removing disks after initial install, which I do imperatively (but still disko for mounting / fstab equivalent)

  • Slightly offtopic, does anyone know how to setup vscode dev containers with podman on NixOS? I tried vscode-fhs and some consulted wiki[0], but encountered some issues with gid ranges for commands like `sudo apt install ...` inside a container.

    Is there an guide for it?

    [0] https://wiki.nixos.org/wiki/Podman

  • While the Nix package manager still has a vertical learning curve, I found NixOS itself to be pretty idiotproof to install, with pretty much the same clicky installer experience as Ubuntu. I do remember a couple of things like `nix search` were broken out of the box -- in fact I don't think I ever got it working, I still just use the website to search for packages.

  • GUIX is a pleasure

  • Anyone know if Nix solved their politics problem yet?

    I see a resultant fork exists in auxolotl.

  • Reminds me of a similar approach with ZFS: https://github.com/ascension-association/zbm-void-ts

  • Title should be: "How I like to install NixOS (declaratively)"

  • [flagged]