1
0
Fork
You've already forked dots
0
No description
  • Nix 90.4%
  • QML 5.8%
  • Shell 3.3%
  • Python 0.5%
2026年07月11日 00:03:40 +02:00
config chore: compositor changes 2026年05月13日 15:21:22 +02:00
modules fix: hyprlock lock speed 2026年07月11日 00:03:40 +02:00
scripts fix: kanata config 2026年05月11日 09:09:54 +02:00
secrets chore: update dapple 2026年06月29日 14:31:15 +02:00
.gitignore chore: formatting fixes and browser session cleanup on shutdown 2026年04月01日 11:00:26 +02:00
.sops.yaml feat: add DNS split routing, tailscale auth, ZFS snapshots, and fixes 2026年05月11日 09:09:47 +02:00
flake.lock chore: update flake 2026年07月09日 19:34:48 +02:00
flake.nix chore: update flake 2026年06月29日 12:53:16 +02:00
README.md build(treefmt): format Python with black 2026年06月29日 14:42:43 +02:00



Jorrit's NixOS configuration & dots

Overview

A flake-based NixOS configuration for two hosts:

  • rocinante — a laptop/workstation (niri Wayland desktop, full app suite).
  • dapple — a bare-metal home server (Jellyfin, Home Assistant, Vaultwarden, Headscale, *arr stack, backups, ...).

Both boot with Secure Boot + Measured Boot (lanzaboote), an ephemeral ZFS root with [preservation] for state, LUKS+TPM2 disk encryption, and [sops-nix] for secrets. Hardware is described declaratively via [nixos-facter].

Layout

flake.nix # inputs only; outputs are assembled by import-tree
modules/
 flake/ # flake-parts plumbing: lib helpers, formatter, checks, home-manager
 features/
 core/ # boot, disk, zfs, preservation, secrets, kernel, locale
 system/ # ssh, sudo, networking, vpn
 services/ # one file per server service (dapple)
 desktop/ # niri compositor, shell, keybinds, theming, session, ...
 apps/ # per-application config (rocinante)
 dev/ # git/jj, direnv, virtualization, coding-agent
 shell/, hardware/
 hosts/<host>/ # configuration.nix + facter.json per machine
 users/<user>/ # per-user config (home-manager via lib.mkUser)

import-tree auto-discovers every .nix file under modules/, so there is no central module registry — adding a file is enough to register it.

Conventions

Every feature is a NixOS module exposed under flake.nixosModules.<name> and gated behind an option in the my.* namespace (e.g. my.jellyfin.enable). The my.* prefix marks "this repo's options" and avoids collisions with upstream NixOS/home-manager options. The standard module shape is:

{
 flake.nixosModules.foo =
 { config, lib, pkgs, ... }:
 let
 cfg = config.my.foo;
 in
 {
 options.my.foo.enable = lib.mkEnableOption "the foo service";
 config = lib.mkIf cfg.enable {
 # ...
 };
 };
}

Persistent state is declared via my.preservation.{systemDirectories,homeDirectories,...} (see modules/features/core/preservation.nix); the ephemeral root is wiped on every boot, so anything not preserved is lost by design.

Adding a module

  1. Create modules/features/<category>/<name>.nix following the shape above.
  2. Add <name> to the host's import list in modules/hosts/<host>/configuration.nix.
  3. Set my.<name>.enable = true; (plus any options) on the host.

Adding a host

  1. Generate hardware facts: nixos-facter -o modules/hosts/<host>/facter.json.
  2. Add modules/hosts/<host>/configuration.nix defining flake.nixosConfigurations.<host> with the shared modules + host options (use an existing host as a template).

Working with the repo

nbuild # build the current host's configuration (dry-run/test)
nswitch # build + switch
nix fmt # treefmt: nixfmt + deadnix + statix + prettier
nix flake check # formatting + statix + builds both hosts

Version control uses [jujutsu] (jj) on a colocated git repo. Secrets live in secrets/ and are decrypted by sops-nix using an age key derived at boot from the host's SSH key.