NixOS Provisioning
Deterministic system builds, flake architecture, and flash workflow.
Overview
Floppy.WTF provisions devices by flashing NixOS using a flake-based system definition. Each device receives a deterministic OS build defined by its assigned role and hardware profile.
Flake Architecture
flake.nix — Build Manifest
Multi-architecture flake supporting x86_64 (laptops, desktops) and aarch64 (Raspberry Pi, SBCs, robots):
{
description = "Floppy.WTF — Deterministic device provisioning";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
home-manager = {
url = "github:nix-community/home-manager/release-24.11";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, home-manager, ... }: {
nixosConfigurations = {
# x86_64 — Dell, generic laptops/desktops
dell-dev = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ... ]; };
dell-proxy = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ... ]; };
generic-dev = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ... ]; };
# aarch64 — Raspberry Pi, ARM SBCs, robots
raspberry-robot = nixpkgs.lib.nixosSystem { system = "aarch64-linux"; modules = [ ... ]; };
raspberry-mainframe = nixpkgs.lib.nixosSystem { system = "aarch64-linux"; modules = [ ... ]; };
raspberry-dev = nixpkgs.lib.nixosSystem { system = "aarch64-linux"; modules = [ ... ]; };
};
# Pre-built SD images for ARM devices
images = {
raspberry-robot = /* ... sdImage ... */;
raspberry-mainframe = /* ... sdImage ... */;
};
};
}Module Composition
Host Config (hardware-specific: dell/, generic/, raspberry/)
│
├── modules/base.nix (always included)
├── modules/filesystem.nix (always included)
├── modules/power.nix (conditional — laptops only)
│
├── roles/{role}.nix (role-selected)
│ └── includes theme + packages + services for that role
│
└── theme/{theme}.nix (role-selected or overridden)Core Modules
modules/base.nix — Core System
Every host includes this. Provides:
- Boot loader (systemd-boot + EFI)
- Networking (NetworkManager)
- Timezone and locale
- Default user (
jeremy) - SSH server
- Nix flakes enabled
- Basic packages (git, vim, htop)
modules/filesystem.nix — Btrfs Layout
Disk Layout (GPT)
├── /boot (EFI System Partition) — 512MB, FAT32
└── / (Root) — Btrfs, remainder of disk
├── @ → / (root subvolume)
├── @home → /home (user data)
├── @nix → /nix (Nix store — large)
├── @log → /var/log (persistent logs)
└── @snapshots → /.snapshots (snapshot storage)Btrfs features enabled:
- Transparent compression (zstd)
- Metadata checksums
- CoW (copy-on-write)
- Automatic scrub schedule (weekly)
modules/power.nix — Power Management
Conditionally included for battery-powered devices. TLP (laptops), CPU governor tuning, lid/suspend behavior.
modules/desktop.nix — Desktop Environment
Default: XFCE (lightweight, GPU-safe across hardware classes) with LightDM display manager and Picom compositor. Omitted for headless roles (node, robot, mainframe, proxy).
Role Taxonomy
| Role | Purpose | Desktop | Typical Hardware | Key Services |
|---|---|---|---|---|
dev | Developer workstation | XFCE + full theme | Laptops, desktops | SSH, Syncthing |
node | Infrastructure node | Headless | Any | SSH, WireGuard, monitoring |
minimal | Bare minimum | XFCE (minimal) | Any | SSH |
lab | Experimentation | XFCE + full theme | Laptops, desktops | SSH, Syncthing, WireGuard |
kiosk | Single-purpose display | Custom (locked) | Terminals, displays | SSH (admin only) |
proxy | VPN exit node | Headless | Desktops, servers | SSH, WireGuard, NAT |
ai | AI inference | Headless | Pi 5, Jetson, desktops | SSH, llama.cpp |
robot | Robot controller | Headless | Pi 4 + HIWONDER | SSH, servo bus, camera, TTS |
mainframe | AI hub / model host | Headless | Pi 5, servers | SSH, Ollama, fleet API |
terminal | Display dashboard | Custom (locked) | Seeed reTerminal | SSH, e-paper/LCD |
Provisioning Workflows
Two paths depending on target hardware.
Path A: USB Flash (x86_64 — laptops, desktops)
- Write NixOS ISO to USB (balenaEtcher or
dd) - Boot target from USB (F12 on Dell, varies by manufacturer)
- Connect to network
- Partition disk (Btrfs layout per filesystem.nix)
- Mount subvolumes, clone repo, generate hardware config
nixos-install --flake /mnt/etc/floppy/nixos#{host}-{role}- Reboot into provisioned system
Path B: SD Image (aarch64 — Raspberry Pi, SBCs, robots)
- Build SD image:
nix build .#images.raspberry-robot - Flash:
floppy provision flash --image ./result/sd-image/*.img - Insert SD, power on, SSH in
- No internet required — everything baked into the image
Automation Target
# x86_64
floppy provision FLOPPY-DEL-00001 --role dev
# aarch64
floppy provision FLOPPY-RPI-00001 --role robot
floppy provision build-sd --target raspberry-mainframeOrchestrates partitioning/imaging, config deployment, installation, verification, and status update.
Integrity Guarantees
Build Reproducibility
flake.lockpins exact nixpkgs commit- Same flake inputs → same system closure hash
- Closure hash verifiable via
nix path-info
Filesystem Integrity
- Btrfs metadata checksums detect corruption
- Weekly scrub validates data blocks
- Snapshots provide rollback points
Store Verification
- Every Nix store path is content-addressed
- Tampering changes the hash → system detects mismatch
nix store verify --allchecks entire store