Each host heading produces a nixosSystem declaration that is shoved in to Arroyo System Flake Generator via ARROYO_OUTPUT metadata. The shared host-modules Lua block resolves role-filtered NixOS modules from the Arroyo DB.
Deploying My Laptops and Desktop
My laptops are installed through my NixOS Automatic Partitioning Installer and carry My NixOS configuration for laptops, the "endpoint configuration".
Virtuous Cassette
Linked from
Virtuous Cassette is my Framework 12 Laptop. It was a Framework 13 for quite some years, but that chassis is my computer for my job now.
nixosConfigurations.virtuous-cassette = mkHost {
name = "virtuous-cassette";
roleModules = [
<<host-modules("endpoint")>>
];
};{ config, pkgs, lib, ... }:
{
imports = [
../../nixos/framework-laptop-12.nix
];
system.stateVersion = "23.11";
sops.age.keyFile = "/home/rrix/.config/sops/age/keys.txt";
networking.hostName = "virtuous-cassette";
boot.loader.grub.efiSupport = true;
boot.loader.grub.device = "nodev";
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.enable = true;
boot.loader.systemd-boot.enable = false;
boot.initrd.luks.devices = {
"swap" = {
name = "swap"; device = "/dev/nvme0n1p2"; preLVM = true;
};
"root" = {
name = "root"; device = "/dev/nvme0n1p3"; preLVM = true;
};
};
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
powerManagement.cpuFreqGovernor = "powersave";
hardware.enableRedistributableFirmware = true;
services.udev.extraRules = ''
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="18d1|096e", ATTRS{idProduct}=="5026|0858|085b", TAG+="uaccess", GROUP="plugdev"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0407", TAG+="uaccess", GROUP="plugdev", MODE="0660"
'';
services.udev.packages = with pkgs; [ platformio-core.udev ];
programs.nix-ld.enable = true;
programs.nix-ld.libraries = with pkgs; [
pkgs.udev
pkgs.SDL2
pkgs.libpng
pkgs.libz
];
hardware.sensor.iio.enable = true;
environment.systemPackages = [
pkgs.maliit-framework
pkgs.maliit-keyboard
pkgs.wl-clipboard
];
sops.secrets.tailscale_virtuous_cassette.owner = "root";
services.tailscale.authKeyFile = config.sops.secrets.tailscale_virtuous_cassette.path;
networking.hostId = "291fe33d"; # required for zfs use
fileSystems."/" =
{ device = "host/root";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "host/home";
fsType = "zfs";
};
fileSystems."/media" =
{ device = "host/landfill";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "host/nix";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/CD54-B840";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/ddfce221-2d29-4882-9c66-1669ea60bc49"; }
];
}Rose Quine
Rose Quine is my GPD Pocket 3.
nixosConfigurations.rose-quine = mkHost {
name = "rose-quine";
roleModules = [
<<host-modules("endpoint")>>
];
};{ config, pkgs, lib, ... }:
{
imports = [ ../../nixos/gpd-pocket-3.nix ];
networking.hostName = "rose-quine";
system.stateVersion = "23.05";
services.xserver.dpi = 280;
sops.secrets.tailscale_rose_quine.owner = "root";
services.tailscale.authKeyFile = config.sops.secrets.tailscale_rose_quine.path;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.device = "nodev";
boot.loader.grub.enable = true;
boot.loader.grub.gfxmodeBios = "1200x1920x32";
boot.loader.systemd-boot.enable = lib.mkForce false;
networking.hostId = "3f5dbbf9"; # required for zfs use
boot.zfs.devNodes = "/dev/mapper"; # (ref:devNodes)
boot.initrd.luks.devices = {
"swap" = {
name = "swap"; device = "/dev/nvme0n1p2"; preLVM = true;
};
"root" = {
name = "root"; device = "/dev/nvme0n1p3"; preLVM = true;
};
};
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "tank/root";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "tank/home";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "tank/nix";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/9FDC-2C40";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/455bbc40-e01c-4137-b593-a05b6220ce6b"; }
];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
}NEXT derivation for umpc-display-rotate.c
NEXT split and document all this out in to an import on GPD Pocket 3 Support page
Window Smoke
:ARROYO_SYSTEM_ROLE: endpoint
:ARROYO_AGE_RECIPIENT: age1<PLACEHOLDER_WINDOW_SMOKE>
#+ARROYO_OUTPUT: snippets/window-smoke.nixWindow Smoke is my desktop. It runs my Endpoint Configuration and some of My NixOS Tower Customizations. These days I just boot it into steam big picture mode and rdp in over Tailscale.
nixosConfigurations.window-smoke = mkHost {
name = "window-smoke";
roleModules = [
<<host-modules("endpoint")>>
];
};{ lib, config, ... }:
{
imports = [ ./hardware-configuration.nix ../../roles/desktop ];
boot.enableVFIO = false;
networking.hostName = "window-smoke";
system.stateVersion = "22.11";
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.systemd-boot.enable = true;
services.xserver.dpi = 110;
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" "wl" ];
boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
sops.secrets.tailscale_window_smoke.owner = "root";
services.tailscale.authKeyFile = config.sops.secrets.tailscale_window_smoke.path;
networking.hostId = "141e1b4f"; # required for zfs use
boot.zfs.devNodes = lib.mkForce "/dev/disk/by-id/";
boot.initrd.luks.devices = {
"swap" = { name = "swap"; device = "/dev/nvme0n1p2"; preLVM = true; };
"root" = { name = "root"; device = "/dev/nvme0n1p3"; preLVM = true; };
};
fileSystems."/" =
{ device = "window-smoke/root";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "window-smoke/home";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "window-smoke/nix";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/12CA-451F";
fsType = "vfat";
};
fileSystems."/media" =
{ device = "tank/media";
fsType = "zfs";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/26776a6d-4e53-4e39-b0e5-5a540ce78406"; }
];
}Meadow Crush
:ARROYO_SYSTEM_ROLE: endpoint
:ARROYO_AGE_RECIPIENT: age1<PLACEHOLDER_MEADOW_CRUSH>
#+ARROYO_OUTPUT: snippets/meadow-crush.nixMeadow Crush is my GPD Pocket 2; I don't use this right now but it's still running a viable NixOS if I need it in a Situation.
nixosConfigurations.meadow-crush = mkHost {
name = "meadow-crush";
roleModules = [
<<host-modules("endpoint")>>
];
};{ config, ... }:
{
imports = [ ./hardware-configuration.nix ../../nixos/gpd-pocket.nix ];
networking.hostName = "meadow-crush";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
sops.secrets.tailscale_meadow_crush.owner = "root";
services.tailscale.authKeyFile = config.sops.secrets.tailscale_meadow_crush.path;
networking.hostId = "c9ec7cad"; # required for zfs use
boot.initrd.luks.devices = {
"swap" = { name = "swap"; device = "/dev/mmcblk0p2"; preLVM = true; };
"root" = { name = "root"; device = "/dev/mmcblk0p3"; preLVM = true; };
};
fileSystems."/mnt/music" =
{ device = "/dev/disk/by-label/muzak";
fsType = "ext4";
noCheck = true;
};
}Deploying The Wobserver and the Edge Server
Last Bank
Linked from
Last Bank is my New Homelab Build, a living-room server that will be proxied through Wobscale Technologies in Seattle, WA. It's going to replace terra-firma.
nixosConfigurations.last-bank = mkHost {
name = "last-bank";
homeManager = false;
roleModules = [
<<host-modules("server")>>
];
extraModules = [
./nixos/home-manager-server.nix
];
};{ lib, config, ... }:
let
in {
# imports = [ ../../roles/desktop ];
# boot.enableVFIO = true;
networking.hostName = "last-bank";
system.stateVersion = "23.05";
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/disk/by-id/ata-Samsung_SSD_870_EVO_1TB_S75BNL0WA24883N";
sops.secrets.tailscale_last_bank.owner = "root";
services.tailscale.authKeyFile = config.sops.secrets.tailscale_last_bank.path;
networking.hostId = "56c334f2"; # required for zfs use
boot.zfs.devNodes = "/dev/disk/by-id"; # (ref:devNodes)
boot.initrd.availableKernelModules = [ "ehci_pci" "ahci" "isci" "usbhid" "usb_storage" "sd_mod" "igb" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "host/root";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "host/nix";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "tank/home";
fsType = "zfs";
};
fileSystems."/media" =
{ device = "tank/media";
fsType = "zfs";
};
fileSystems."/srv" =
{ device = "tank/srv";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/19C9-747A";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-id/ata-Samsung_SSD_870_EVO_1TB_S75BNL0WA24883N-part2"; }
];
boot.initrd.network = {
enable = true;
ssh = {
enable = true;
port = 2222;
hostKeys = [ /home/rrix/arroyo-nix/files/last-bank-initrd-host-key ];
authorizedKeys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCt7MT45sX7yML+aUqWUC2RZdxhVpoGz2XLEDes/h0HnvwkV8ZURSBAlkwSAH5Sd2c6nyego0GsvkOUppeqoKtacMz6JK5iut3hMWiR6NcSZfG7r8NR5/WrPpWwGtU7cRkkxVKM1PwtYk0crQTCVg5G9+9quKtGkEQ33ile5XSr2VVO44hWafZlSLPFPXTLvxgm7MN9E28k7hVeDBIYppM6VnWz5xsbhboKJMSHU8SFPQKw2GqaugDqokeS0SbyCj7poj1uyijQx3hw0RTpzy1XrmCFu4HmT7qgpESi+1aMObItezKyHy6zBh58DF3Hu/T3tqFglR6XbyfsR3IHyTVz rrix" ];
};
# postCommands = ''
# zpool import -a
# echo "zfs load-key -a; killall zfs" >> /root/.profile
# '';
};
# greetz https://elis.nu/blog/2026/04/nixos-zfs-remote-unlock-over-ssh/
boot.initrd.systemd.services.zfs-setup-root-profile = {
description = "Prepare root .profile for ZFS unlocking via SSH";
wantedBy = [ "initrd.target" ];
before = [ "initrd-root-fs.target" ];
unitConfig.DefaultDependencies = false;
script = ''
mkdir -p /var/empty
echo "systemd-tty-ask-password-agent --watch" > /var/empty/.profile
'';
serviceConfig.Type = "oneshot";
};
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}King Mountain
The Wobserver's Edge Server in seattle, this exists so that my homelab doesn't need to put my home IP on the public internet.
King Mountain is The Wobserver's Edge Server, a small VM hosted by Wobscale Technologies in Seattle, WA so that my Wobserver doesn't need a public IP.
nixosConfigurations.king-mountain = mkHost {
name = "king-mountain";
roleModules = [
<<host-modules("edge")>>
];
};{ lib, config, modulesPath, ... }:
{
imports = [
"${toString modulesPath}/profiles/qemu-guest.nix"
];
networking.hostName = "king-mountain";
system.stateVersion = "24.11";
sops.secrets.tailscale_king_mountain.owner = "root";
services.tailscale.authKeyFile = config.sops.secrets.tailscale_king_mountain.path;
networking.hostId = "66c334a2"; # required for zfs use
boot.zfs.devNodes = "/dev/disk/by-uuid"; # (ref:devNodes)
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
autoResize = true;
fsType = "ext4";
};
boot.growPartition = true;
boot.kernelParams = ["console=ttyS0"];
boot.loader.grub.device = "/dev/sda";
boot.loader.timeout = 3;
boot.initrd.availableKernelModules = [ "ehci_pci" "ahci" "isci" "usbhid" "usb_storage" "sd_mod" ] ++ [
"virtio_net"
"virtio_pci"
"virtio_mmio"
"virtio_blk"
"virtio_scsi"
"9p"
"9pnet_virtio"
];
boot.initrd.kernelModules = [
"virtio_balloon"
"virtio_console"
"virtio_rng"
"virtio_gpu"
];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}Deploying the Inference Server and Langlemangler VM
Tomorrow Untrodden
Tomorrow Untrodden is the Wobserver's Inference Server. It provides compute for the langlemanglers, clankers, and similar things.
nixosConfigurations.tomorrow-untrodden = mkHost {
name = "tomorrow-untrodden";
roleModules = [
<<host-modules("clanker")>>
];
};{ lib, config, modulesPath, inputs, ... }:
{
imports = [
"${inputs.nixos-hardware}/framework/desktop/amd-ai-max-300-series"
];
networking.wireless.enable = true;
networking.networkmanager.enable = true;
networking.hostName = "tomorrow-untrodden";
system.stateVersion = "26.05";
sops.secrets.tailscale_tomorrow_untrodden.owner = "root";
services.tailscale.authKeyFile = config.sops.secrets.tailscale_tomorrow_untrodden.path;
networking.hostId = "f8b9975f"; # required for zfs use
boot.zfs.devNodes = "/dev/mapper"; # (ref:devNodes)
boot.loader.grub.efiSupport = true;
boot.loader.grub.device = "nodev";
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.enable = true;
boot.loader.systemd-boot.enable = false;
boot.initrd.luks.devices = {
"swap" = { name = "swap"; device = "/dev/nvme0n1p2"; preLVM = true; };
"root" = {name = "root"; device = "/dev/nvme0n1p3"; preLVM = true;};
};
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "host/root";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "host/home";
fsType = "zfs";
};
fileSystems."/media" =
{ device = "host/landfill";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "host/nix";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/99A8-218C";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices =
[ { device = "/dev/mapper/swap"; }
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
# linux-firmware blobs (mt7925 Wi-Fi/BT RAM codes, optional amdgpu ISP bin)
# come from the redistributable-firmware set.
hardware.enableRedistributableFirmware = true;
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
networking.useDHCP = lib.mkDefault true;
}Sunset Dept
Sunset Dept is the langlemangler's dedicated machine: a plain QEMU guest on Last Bank that owns a persistent full boot disk instead of riding the MicroVM harness.
The runner on Last Bank seeds a ~100G qcow2 from the flake-built disk image once; the guest then manages itself with =nixos-rebuild switch --flake /home/rrix/nix#sunset-dept= over the virtiofs shares. See the guest runner module and the guest modules and bootstrap runbook.
nixosConfigurations.sunset-dept = mkHost {
name = "sunset-dept";
flake = inputs.nixpkgs-unstable;
homeManagerModule = inputs.home-manager-unstable.nixosModules.home-manager;
overlays = [
(import ./nixos/langlemangle-vm-pkgs.nix { inherit inputs; })
];
roleModules = [
<<host-modules("langlemangle")>>
];
};{ lib, config, modulesPath, ... }:
{
imports = [
"${toString modulesPath}/profiles/qemu-guest.nix"
"${toString modulesPath}/virtualisation/disk-image.nix"
];
image.efiSupport = false;
image.format = "qcow2";
system.build.diskImage = config.system.build.image;
networking.hostName = "sunset-dept";
system.stateVersion = "26.05";
boot.loader.grub.enable = true;
boot.growPartition = true;
boot.kernelParams = [ "console=ttyS0" ];
boot.loader.timeout = 3;
boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_blk" "virtio_net" ];
boot.initrd.kernelModules = [ "virtiofs" ];
fileSystems."/home/rrix/Code" = {
device = "code";
fsType = "virtiofs";
};
fileSystems."/home/rrix/org" = {
device = "org";
fsType = "virtiofs";
};
fileSystems."/home/rrix/nix" = {
device = "nix";
fsType = "virtiofs";
};
systemd.tmpfiles.rules = [
"d /home/rrix/Code 0755 rrix humans -"
"d /home/rrix/org 0755 rrix humans -"
"d /home/rrix/nix 0755 rrix humans -"
];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
sops.secrets.tailscale_sunset_dept.owner = "root";
services.tailscale.authKeyFile = config.sops.secrets.tailscale_sunset_dept.path;
}Deploying My NixOS Set Top Box
Tres Ebow
Linked from
:ARROYO_SYSTEM_ROLE: settop
:ARROYO_AGE_RECIPIENT: age1<PLACEHOLDER_TRES_EBOW>
#+ARROYO_OUTPUT: snippets/tres-ebow.nixTres Ebow is my Thinkpad Yoga gen 3 -- a decent 2-in-1 with very un-Lenovo serviceability, and due to ordering error and soldered RAM, only 4 GiB of RAM. awkward. it'll be a fine kodi box.
nixosConfigurations.tres-ebow = mkHost {
name = "tres-ebow";
roleModules = [
<<host-modules("settop")>>
];
};{ config, lib, ... }:
{
networking.hostName = "tres-ebow";
boot.loader.grub.efiSupport = true;
boot.loader.grub.device = "nodev";
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.enable = true;
boot.loader.systemd-boot.enable = false;
services.xserver.dpi = 207;
networking.hostId = "389acda5"; # required for zfs use
boot.zfs.devNodes = lib.mkForce "/dev/disk/by-uuid"; # (ref:devNodes)
sops.secrets.tailscale_tres_ebow.owner = "root";
services.tailscale.authKeyFile = config.sops.secrets.tailscale_tres_ebow.path;
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "host/root";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "host/home";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "host/nix";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/CB62-8263";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/4f1751ef-0ddd-4005-b69c-daafc518e9df"; }
];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "balanced";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
hardware.enableRedistributableFirmware = true;
}Shared Generator
host-modules(role) queries the DB for ARROYO_NIXOS_MODULE entries filtered by role and returns ./modulePath lines.
local modules = arroyo.nixos_role_modules(role)
local lines = {}
for _, m in ipairs(modules) do
table.insert(lines, "./" .. m.module_path)
end
return table.concat(lines, "\n ")