Skip to content(if available)orjump to list(if available)

How I like to install NixOS (declaratively)

perrygeo

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.

codethief

> 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.

For Python I use uv to download & set up Python binaries outside Nix. To make them work I enabled nix-ld in my Nix config, so there's a default linker & libc they can access. Works well so far.

grep_name

C/C++ is a PITA and I'm not a C/C++ developer, but I do find that I'm able to get around the issue 90% of the time using steam-run (although that feels kludgy as hell and I really wish there were a better option for getting linked libraries working normally). I think the real answer is to get good enough with nix to build a flake quickly for the project you're working with, but that seems like a lot to learn. Maybe easier if you're more familiar with C/C++ dependencies and build tools than me though.

Musnix looks really interesting. My whole audio setup looks like this in my nixconfig:

   hardware.pulseaudio.enable = false;
   services.pipewire = {
     enable = true;
     alsa.enable = true;
     alsa.support32Bit = true;
     pulse.enable = true;
     jack.enable = true;
   };

   hardware.bluetooth.enable = true;
   hardware.bluetooth.powerOnBoot = true;
   services.blueman.enable = true;

This works great for my workflow of using headphones + BT 100% of the time, but weirdly it almost never works for the built-in speakers on my framework. I might try musnix if that ever bothers me, but it's actually kind of a feature for me since my laptop can never just start blaring whatever I was watching / listening to into public

nextos

FWIW, I think pipewire has been enabled by default for some time in Nix right now?

Cloudef

nix-ld is the better way

grep_name

This looks interesting, just speed-read the readme. Is there a way to use this from the commandline, similar to steam-run, if you're just trying to sloppily check out some repo without building a whole flake?

jjmarr

> I think the real answer is to get good enough with nix to build a flake quickly for the project you're working with

I just have AI do it. Any of the coding assistants with terminal access can write and test flakes for you.

grep_name

I tried doing it for awhile but wasn't able to ever get it to work for the main project I was trying to build, which was a VR project called LÖVR. I could have made and submitted a package using one of their appimage releases, but was doing it as an exercise to see how far I could push things.

I also went through a phase where I had AI write a lot of simpler flakes, but they turned out surprisingly different from each other, enough so that I wasn't able to learn a pattern as a base to grok what was happening. At some point I'll try again from first principles, but for some reason the AI flakes hindered more than helping

jchw

> 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.

Depending on your individual use case you might find it sufficient to simply work on and compile software inside of Distrobox. It integrates nicely enough with the host system I think.

Personally, I usually do a small bit of hackery to get a good dev environment for C++ projects, using a combination of flakes and envrc. It's not exactly elegant, but you can re-use the Nixpkgs derivation for the actual dev shell. If you need to, you can even reuse the Nix patchPhase from the real derivation to apply NixOS-specific patches to your local tree temporarily.

The fact that it's possible to get a decent experience with not really that much effort kind of signals to me that it probably could be a lot better. On the other hand, maybe in a better Nix world, Nix could become even more integrated into both the dev and build process: with dynamic derivations the build process could be broken up into many smaller derivations and give Bazel-like behavior.

One thing I really enjoy about Nix is how easy it is to have different shells to use for different things without needing to pollute the system with tons of packages you needed for only one thing, but on the other hand the rest of the world doesn't integrate perfectly with this. For example, a lot of GUI text editors manage their own processes, so you can't just start a new window already inside of a shell. For VS Code derivatives the envrc extension kind of works, but it's a bit of a hack. A good improvement would be developer tools explicitly supporting this model, and as Nix seems positioned to continue to be gradually more relevant over time, I am hopeful it will become important enough for tools like VS Code to consider.

I have had a decent time, though. I have a mostly automated approach to getting working clangd and incremental compilation with pretty much any project, with just a little bit of mucking about with boilerplate.

whateveracct

> 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.

I think it's a testament to Nix's promise. Abstraction with capital A!

riehwvfbk

It's most likely not C/C++ per se, but rather the eleventy billion ways different projects build these libraries.

Bazel for example builds everything in a well-contained sandbox and it all works, but only for the C/C++ libraries it builds natively. The magic ingredient is RPATH, but most Makefiles do not set it. However, one can add an extra build step with patchelf and inject an RPATH.

MuffinFlavored

> Linux audio is a confusing disaster and I'd basically given up on Ubuntu

Have you considered buying a MacBook and valuing your free time more?

uselesswords

Some of us also value having freedom in what we use for the majority of our day.

rowanG077

Pretty wild to say osx and valuing free time. Everytime I have to do anything that is one millimeter of the beaten path it turns into a momentous time sink. And than more often than not you figure it's impossible to do what you want.

MuffinFlavored

You're lying to yourself if you think people spend time playing with audio drivers/configuration to get sound working on Mac.

bjackman

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!

Jhsto

Another option is to run it ephemerally from the RAM. I have been doing this for my laptop and servers for years now. You can do so by declaring the following: https://github.com/ponkila/HomestakerOS/blob/main/nixosModul...

You need to then have a flake which defines a "package" like this: https://github.com/jhvst/nix-config/blob/main/flake.nix#L117...

Now you can run 'nix build .#starlabs' which will create you the files needed for kexec / PXE booting.

You can also write tests that these images actually boot ok: https://discourse.nixos.org/t/nixostest-with-flake-configura...

I started working on this stuff because I needed to somehow reliably update my homeserver. I live abroad 50 weeks a year, so I needed something reliable because I can't assume I have physical access to the computer. Even when the BMC firmware got screwed by ASRock motherboard firmware, I didn't need to sweat.

Now for the shameless plug: my company created a PXE server module which also supports flakes that assumes this ephemeral setup. It's described in here: https://github.com/majbacka-labs/nixos.fi

bjackman

Ah yes this also looks fantastic and something I intend to try.

At $work we have insane platforms that are extremely hostile to platform development but they do support a (obviously annoyingly custom and limited) PXE-like thing and I'm hoping I can boot NixOS via that and just never even touch the disk (which is full of insane custom $work platform bullshit).

diggan

> I never really feel 100% confident that something is gonna work as I hope until I physically try it

I ended up in the same situation too, but discovered relatively quickly that NixOS makes it really easy to build clean VMs from your config that you can run and test against, then when validated, you apply the configuration to the actual hardware.

I'm doing this for all my servers managed with NixOS right now, and managed to prevent multiple issues being deployed, including something that would prevent a clean boot and since the host is headless, would have required me to connect monitor and keyboard in order to recover.

Really glad NixOS is setup the way it is, although you're right the learning curve is rough. At least I can easily re-install my infrastructure really trivially, which helps me sleep at night.

zxexz

I’m using that exact feature for a blue/green/another color deploy setup, it’s very nice. The server with the hosted application builds a vm of itself, run some checks. Route traffic to (RR). If it’s all good, send the VM to a secondary house and route to there. On the primary, reboot (usually kexec). Switch back over.

Should probably just be using a persistent but this is some pretty heterogenous hardware and…it works

bjackman

Yeah I make extensive use of this and it's absolutely fantastic.

I can write a config, very quickly check it seems correct on a QEMU guest, and then deploy "the same" config to a physical host (slower to boot, harder to debug, annoying to power cycle) and be highly confident it's gonna behave like the VM did. This is incredibly valuable!

But by "hard to know if it's gonna work" I was talking more about architecture-level concerns. Not "is my Nix code correct" but "is this thing I'm envisaging a thing that the ecosystem supports?" I usually just have to sit down and try coding it up, and there's always an element of uncertainty about whether I'll succeed. Whereas if I sit down to get something done in Ansible I don't really have any such doubts. (But the result will be dramatically worse).

tlavoie

Regarding how a bunch of the pieces go together, I found this blog post from Shopify quite useful: https://shopify.engineering/what-is-nix

woile

how do you do this and what do you use? do you just manually trigger qemu? I'd love to be able to boot VM with different nix configurations.

femiagbabiaka

> 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.

One of the most underrated features of Nix imo is the testing story. You absolutely can be confident that something will work!

https://nixcademy.com/posts/nixos-integration-tests/

bjackman

Yea I agree on that front. But I don't mean "it's hard to write correct Nix configs" I mean that without a lot of experience it's hard to design a Nix system in your head and know whether the design is naturally supported by the ecosystem or if you're kinda going off into uncharted territory.

It's usually pretty easy to try stuff and I really like the way once you have learned something, you can't ever really forget it because everything is code. I know lots of things say "it's config-as-code!" but very few do hermeticity as well as Nix. In that regard it has some of the benefits of monorepo life, without needing an actual monorepo.

amelius

> It does have a really harsh learning curve though.

Would it be possible to automatically translate all Nix build scripts into a language that is more ergonomic and fun to work with?

danieldk

Nix guarantees that a given derivation will always evaluate to the same store .drv (the 'recipe' that is actually built) if the derivation itself (or anything it depends on, passed as arguments) does not change.

This property requires a pure language with no side-effects. Nix was not completely pure (e.g. `currentSystem` and `getEnv` were impure), but Flakes close this gap.

You could of course generate Nix from another language (or .drvs), but you probably want to keep the same guarantees.

Besides that, Nix itself is actually a pretty simple functional programming language. The difficulty is probably for most people knowing/understanding everything that is built on top of it: fixed points, overlays, nixpkgs.lib, stdenv, overriding, hooks, all the programming-language specific builders, etc. It is a pretty big ecosystem and a lot of it is not very well documented.

That said, when I started using nixpkgs/NixOS in 2018, it was the easiest package ecosystem to start contributing too. RPM .spec and Debian rules files are quite archaic, nixpkgs was really a breath of fresh air. It's just that because NixOS is very principled and does not follow HFS, you have to become a packager yourself much sooner than most other distributions to get stuff working. (Though this changed a bit with nix-ld.)

bjackman

As others have said, this would be a solution to the wrong problem. The language itself is fine. I just read through the language intro on https://nix.dev and immediately just "got it" - if you've done any functional programming at all and/or used stuff like JSonnet/Cue there's not much to learn.

But also the fundamental model of Nix is incompatible with anything that can be translated to a simple Bash script. If you could translate it to Bash I wouldn't wanna use it

But yeah the difficulty is the ecosystem. "Nix" is a lot of things and all of those things are individually extremely flexible. This adds up to a system that can do almost anything and that inevitably makes it kinda hard to break into. The docs are honestly better than I could do but documenting this system just seems unbelievably hard to do well.

huimang

The learning curve isn't due to the language, and personally I find writing nix files to be much more pleasant than any other build system I've worked with, and most languages that I've worked with.

mikepurvis

Absolutely this. Everyone fixates on the language but the hard part is really the packaging ecosystem and how-do-I-X type questions where Nix has ten answers that are all better than what Debian or Arch can do, but it's not obvious which is the best between them or how they compare.

See things like Python packaging, how to make ISOs/installers/containers, how to override a scope, how to maintain a dev environment, how to do package testing, how to set up your own CI with caching and binary delivery, etc.

carlhjerpe

Honestly just start "vibe coding".

After some discussion and iteration with Copilot I had a derivation that pulls the CSI protobuf spec and dumps python code and types into something LARPing as a real python library.

A few hours later I implemented my own CSI driver using these things.

Github crawls nixpkgs and everyone and their aunt have public nixos configs, the LLM is good at Nix.

That all nix build instructions are bash isn't the worst, and I hate bash. You can always create a python script to call in a derivation if you need.

bjackman

Yeah I have had some luck with vibe coding Nix but also I've found you have to be extremely cautious. It bullshits a LOT more than with other coding things I use LLMs for. This has led me on a couple of wild goose chases.

I think it helps to have comments like

# AN AI WROTE THIS BIT, REUSE WITH CAUTION

otabdeveloper4

No, because the Nix language is already ergonomic and fun. Any other language will make it worse.

It's a difficult problem domain that isn't solved with syntax sugar.

secure

Glad to hear that the article describes exactly what you need :)

Try out building an installer and run it in a VM, it only takes a few minutes!

FireBeyond

> 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.

It's huge. I tried learning and exploring Nix Darwin. Went through at least half a dozen blog posts with "step by step" instructions. All different. All had some fatal error at some point even on a new install of macOS that was from moderate to impossible to find coherent help on.

s0l1dsnak3123

I started with Nix darwin, and it's definitely buggier and less well supported compared to nix-proper. I'd recommend trying out building a NixOS VM for a better introduction to Nix.

7bit

I dtarted my Linux journey 3 weeks ago with Arch and Ansible to create a declarative system. The installing-part however was tricky, because I have a second disk with Windows and I want to use secure boot. And if I wanted to use Ansible, I would have to create a specific ISO. And then I would have to manually define the disk I want to use or run into the risk of formatting the wrong one and lose a lot of data.

Then I found NixOS, which is like Ansible, but better, because Ansible only adds information to a system, but NixOS also ensures that anything that is not declared is removed as well.

After three weeks, I realized that the effort to declaratively (or automate an imperstively) install the OS is such a lot of work that does not pay off if you're not going to install multiple systems each week or month.

How many commands does it take to actually install NixOS? You partition the disk which take 3 commands. Then you format it, which takes 3 commands. Then you mount the disks, which takes 3 commands. Then you install it, download your configuration and apply it, which is another 2-3 commands.

It takes 5 minutes vs whatever effort you put into creating a declarative installer and keeping that up to date. I also had to think of the time it would cost me to actually figure out HOW a declarative installation would work and the tools I would require. I reckon that the first 24 system would essentially be free (opposed to the 2 hours or so it would cost me to figure out declarative OS installations).

I decided that for me, it is not worth it, although I am the type of personality that just hates not automating things.

jorvi

Declarative management of your OS is in terms of effort basically an inversion of imperative management.

With declarative, you frontload an enormous amount of effort:

- You have to learn your declarative framework

- Then you have to slowly build your configuration base, or copy someone else's and figure out why they did what.

- Then you have to figure out workarounds for things that aren't natively managed declaratively.

- Then you start writing your own little helper functions and modularize things. At this point, it starts getting very smooth.

From there on, adding another package or another machine is very very easy, basically adding a few lines of code. And now your system is mostly reproducible, putting you far ahead of an imperative configuration.

Compared to that, doing it imperatively you can just sort of do your thing and roll with it. This let's you do whatever you aim to achieve very quickly, but as time goes on you have to juggle so many balls in terms of tracking and remembering what you configured / what state your config is in that it quickly becomes impossible.

Declarative OS management really sticks once you accept that the first few weeks are gonna suck and the first few months are still gonna have friction. But once you get over the hump, the rewards are there to reap.

SkiFire13

I feel like a lot of that effort could be reduced though:

> You have to learn your declarative framework

Could the framework be simplified so that you don't need to learn all of it but rather just a small part when you're only doing basic stuff?

> Then you have to slowly build your configuration base, or copy someone else's and figure out why they did what.

Couldn't pre-made configurations be made available? For example in docker it's very easy to base your image on another image from an online registry.

> Then you have to figure out workarounds for things that aren't natively managed declaratively.

This is unfortunately a consequence of the current ecosystem essentially being imperative-first, but I wouldn't consider it an intrinsic limitation of declarative systems.

> Then you start writing your own little helper functions and modularize things. At this point, it starts getting very smooth.

This is probably the part where you really need to spend a lot of effort, but I wonder if it's possible to reduce the need for these helper functions and modularization or provide them by default for at least most common cases. Then most wouldn't need to spend the effort for them because they either already exist or there would be no need for them.

prmoustache

> Declarative OS management really sticks once you accept that the first few weeks are gonna suck and the first few months are still gonna have friction. But once you get over the hump, the rewards are there to reap.

Only if you don't change your mind and do not decide to try out that new cool distro that just came out 6 months later.

I like declarative management but so far I have sticked to puppet for that. Sure like with ansible puppet needs to be installed first but on the other hand you can quite easily convert/reuse a config for say debian, to ubuntu, arch or fedora. The main differences are usually package names.

bjackman

Yeah maybe I should have mentioned that despite my enthusiasm I haven't bothered to install NixOS on my laptop or anything! I might one day, but that will be "for the love of the game" not because I expect it to save me any time. Until then, an incredibly basic dotfiles manager is perfectly good enough.

But for setting up appliances, test machines, it's perfect. If I ran cloud VMs I'd also consider it for setting those up.

secure

Welcome to Linux!

I agree that through the lens of “how much time do you save?”, automating a NixOS installation is not worth it. As you describe, it’s just a few interactive commands in the upstream installer.

But from the perspective of “how much effort is it to spin up a new VM for this new project / task?”, spending the extra few minutes on building the fully automated installation path is well worth it. Also consider the perspective of “how many steps does it take to recover this VM in a disaster scenario?”, where reducing the manual steps to a minimum is very helpful.

BTW, the maintenance of the installer is virtually free: The configuration I show is the configuration I use in NixOS as well, so that needs to be updated anyway. Aside from that, to rebase my installer from NixOS 24.11 to NixOS 25.05, I just changed a number. When setting up a new machine, I can either download the upstream installer and write it to a USB stick, or I can change a number, rebuild (< 2 minutes) and write to a USB stick. Really not much difference.

dankobgd

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.

femiagbabiaka

Interesting, I’m not sure how you managed to get conflicts between packages, that’s a violation of the Nix model. If you describe the issue more I’d like to dig into it, even if you don’t use Nix any longer it’d be nice to fix the issue for those who do.

dankobgd

I forgot exactly what it said in error msg, but it was some conflict with like Meson build file apparently already existed or something

femiagbabiaka

Interesting, I’ll try to repro! For clarity, each “derivation” (lets say package) builds in its own hermetically sealed filesystem with its own dependencies. So conflicts in build system configuration shouldn’t be possible unless those packages are doing something impure (unlikely since the Nixpkgs CI tests for it) or the end user is doing something impure (still really hard to do).

hgl

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...

secure

> Almost none of the packages the author listed get used, including zsh

Just to clarify: the point of having packages like lshw and zsh available is not for the case of performing the automated installation (where, yes, they are not used), but for the case where I want to interactively poke around in a booted installer to inspect the target system.

hgl

That's fair, having a remote shell environment that you feel comfortable to poke around is pretty great.

For git, you commented "for checking out github.com/stapelberg/configfiles". I wonder if you sometimes install NixOS locally from the installer? If so, I can understand having those packages around can be very useful.

secure

Yes, I use this same config snippet throughout my installs and haven’t gotten around to managing my home with Nix yet.

Later, I refactored this config snippet into a Flake that I include: https://github.com/stapelberg/nix/ …but that’s for a follow-up blog post :)

dicytea

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

This is only true if you use the disko-install tool, which is a horrible footgun[^1]. The safest approach is to just use the default disko command, then nixos-install.

[^1]: https://github.com/nix-community/disko/issues/947

hgl

Thanks for bringing the disko command to my attention.

However, since we are talking about installing NixOS declaratively, and it's done through nixos-anywhere, which will install it[0] to the ram unfortunately.

[0]: https://github.com/nix-community/nixos-anywhere/blob/abb0d72...

eptcyka

The beauty of nix is that you can trivially build a custom installer - I do it all the time, for each different host. Since it is simple to do, you can choose to make trivial changes. You do not have to, but you definitely can.

Mic92

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).

a_t48

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. :)

bqmjjx0kac

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...

tracnar

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.

edude03

I built something like this a few years ago. Essentially how it worked is you'd specify the path to a nix flake in the kernel parameters, and once the installer was booted it would pull that flake and run it (which ran the installer, formatted the disks and restarted the system). It was part of a larger project but I wonder how the nix team would feel about a small binary that would be included in the default installer image that does this

s0l1dsnak3123

I'd love to see something like this. The lack of installer automation in the official installation docs was surprising to me when I first started.

gigatexal

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.

vincentkriek

The language and the compiler infrastructure is for me the biggest problem. It's very hard to understand what is going wrong when it goes wrong. Most advice feel like copy pasting existing code without knowing what it does.

Learning this also complicates things as I am feeling overwhelmed with all the things needed for simple configuration structures instead of starting out with a simple program.

nothrabannosir

The language is bad but the module system is even worse. It’s another language implemented in the nix language. Zero hopes of an LSP or any kind of editor assistance. God have mercy on your soul if the docs for your piece of work are lacking.

Not a controversial opinion even in the nix community as far as I know.

vendiddy

I think a lot of people including myself feel this way.

I really like the Nix model of derivations and approach to deterministic builds. It's the language IMO that prevents it from getting mainstream adoption.

I think they would be best served by picking a subset of an FP language that already has good ergonomics and tooling.

woile

it's the biggest painpoint. I got used to it, but still don't like it that much. I think there are some efforts to build some kind of VM so, in theory, you could put any language on top.

https://snix.dev/

dogmatism

Have you looked at Guix?

gigatexal

Yes I have. And it looks sane. The language is a kind of lisp? Scheme? It’s what I’d use if I went this route.

mauflows

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)

sohrob

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.

lolinder

> I don't want to have to dig into a config file for every little aspect of my OS to be in working order

When I see comments like this about NixOS I feel like I must have been using a different breed of distro before and switched to a different NixOS than you did.

My experience has been that other distros—even the supposedly stable ones like Debian—are disasters waiting to happen with no clear way of understanding what goes wrong when you do an upgrade and it breaks. Instead of one config file to troubleshoot I have hundreds of config files that I don't even know about that might be at fault. Or it could be not even a config file, it could be that there's a version mismatch that can't be resolved.

For me NixOS's config file is a breath of fresh air. If something on my system breaks it's because I made a change to that single config file. If something on my system isn't working yet it's fixable in that single config file.

The system is far from perfect, but it's much better than the black magic that other distros lean on.

breakds

I think having to debug to find problem of your system is frustrating. But with NixOS, I at least won't be afraid of "breaking the system" or doing something "irreversible". This is totally a peace of mind when tinkering with my setup.

mighmi

GUIX is a pleasure

djrj477dhsnv

The Guix documentation is such a breath of fresh air after struggling with NixOS.