My nix-darwin and NixOS config
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: topology diagram

+208 -148
+13
.markdownlint.yaml
··· 1 + # markdownlint configuration 2 + # https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md 3 + 4 + # MD013: Line length 5 + # Tables and code blocks are exempt — long lines there are unavoidable. 6 + # Prose limit raised to 120 to allow natural sentence flow. 7 + MD013: 8 + line_length: 120 9 + tables: false 10 + code_blocks: false 11 + 12 + # MD033: Inline HTML — allowed for badges and image floats in README 13 + MD033: false
+25 -37
CLAUDE.md
··· 16 16 17 17 ### Single Source of Truth 18 18 19 - All configurable values — username, timezone, theme, packages, feature flags — are declared with typed defaults in **`modules/options.nix`**. Everything else reads from there. 19 + All configurable values — username, timezone, theme, packages, feature flags — are declared 20 + with typed defaults in **`modules/options.nix`**. Everything else reads from there. 20 21 21 22 - System modules: `config.myConfig.*` 22 23 - Home-manager modules: `osConfig.myConfig.*` ··· 40 41 41 42 ### No Custom Abstraction 42 43 43 - The old `cfgLib` helper was removed. Use the plain NixOS module system. See `lib/USAGE.md` for patterns including package resolution and authorized SSH keys. 44 - 45 - ## Directory Layout 46 - 47 - ``` 48 - flake.nix # Defines all hosts; entry point 49 - modules/ 50 - options.nix # ⭐ All option declarations and defaults 51 - common.nix # Shared NixOS settings (GC, auto-upgrade) 52 - desktop.nix # KDE Plasma 6 + SDDM 53 - gaming.nix # Steam + Gamemode 54 - packages.nix # Desktop system packages 55 - services.nix # Printing, Bluetooth, etc. 56 - users.nix # User accounts 57 - server/ # Headless server sub-modules 58 - darwin/ # macOS-specific modules 59 - hosts/ 60 - laptop/ # Host-specific overrides 61 - server/ 62 - macmini/ 63 - home/ 64 - default.nix # Home-manager entry point 65 - programs/ # Per-program configs: git, zsh, ssh, vscode, kde, starship… 66 - settings/ 67 - darwin/ # macOS system.defaults (Dock, Finder, trackpad) 68 - plasma/ # KDE Plasma declarative settings 69 - profiles/ # Reusable config profiles (server-base, server-hardened) 70 - secrets/ # sops-encrypted secrets (age) 71 - tools/ # Rust maintenance utilities (health-check, flake-bump, gen-diff) 72 - lib/USAGE.md # Module patterns reference 73 - docs/ # Extended documentation 74 - ``` 44 + The old `cfgLib` helper was removed. Use the plain NixOS module system. 45 + See `lib/USAGE.md` for patterns including package resolution and authorized SSH keys. 75 46 76 47 ## Building 77 48 ··· 104 75 105 76 Run `health-check` before rebuilding to catch common issues early (daemon, lock file, git cleanliness, age key, disk space). 106 77 78 + ## Infrastructure Diagrams (nix-topology) 79 + 80 + SVG diagrams are auto-generated from NixOS configs. Physical connections and networks are defined in `topology.nix`. 81 + 82 + ```bash 83 + nix build .#topology.x86_64-linux.config.output 84 + # SVGs in ./result/ 85 + ``` 86 + 87 + When adding a new host, add its interfaces and physical connections to `topology.nix`. 88 + Service/interface data is extracted automatically from the NixOS module. 89 + 107 90 ## Secrets 108 91 109 92 Uses [sops-nix](https://github.com/Mic92/sops-nix) with age encryption. ··· 129 112 | home-manager | release-25.11 | 130 113 | nix-darwin | nix-darwin-25.11 | 131 114 | sops-nix | latest | 115 + | nix-topology | latest | 132 116 | plasma-manager | latest | 133 117 | catppuccin | latest | 134 118 | nix-vscode-extensions | latest | ··· 138 122 139 123 ## Running Tools 140 124 141 - Unless a tool is explicitly listed as a shell alias or known to be installed, always use `nix run` rather than assuming it's on `$PATH`: 125 + Unless a tool is explicitly listed as a shell alias or known to be installed, 126 + always use `nix run` rather than assuming it's on `$PATH`: 142 127 143 128 ```bash 144 129 nix run nixpkgs#<package> -- <args> ··· 152 137 nix run nixpkgs#nixfmt-rfc-style -- file.nix 153 138 ``` 154 139 155 - The maintenance tools (`health-check`, `flake-bump`, `gen-diff`) are the exception — they have shell aliases and are available after a rebuild. 140 + The maintenance tools (`health-check`, `flake-bump`, `gen-diff`) are the exception — 141 + they have shell aliases and are available after a rebuild. 156 142 157 143 ## Code Style 158 144 159 145 - Formatter: `nixfmt-rfc-style` (run `nix fmt`) 160 146 - Follow existing patterns in the file you're editing 161 - - Keep options in `modules/options.nix` grouped by domain with `# ── Domain ──` headers 147 + - Keep options in `modules/options.nix` grouped by domain with 148 + `# ── Domain ──` headers 162 149 - Prefer `lib.mkIf` over `if/then/else` blocks at the top level 163 150 164 151 ## Common Tasks ··· 173 160 174 161 1. Create `hosts/<hostname>/default.nix` 175 162 2. Add hardware config (NixOS: `nixos-generate-config`) 176 - 3. Add entry in `flake.nix` under `nixosConfigurations` or `darwinConfigurations` 163 + 3. Add entry in `flake.nix` under `nixosConfigurations` or 164 + `darwinConfigurations` 177 165 4. See `docs/hosts.md` for the full guide 178 166 179 167 **Add a new home-manager program:**
+62 -111
README.md
··· 1 1 # Nix Configuration 2 2 3 - v0.4.0 3 + v0.5.0 4 4 5 5 Personal NixOS and nix-darwin configurations for managing multiple 6 6 machines with a unified, centralized setup. ··· 16 16 17 17 ## Key Features 18 18 19 - ✨ **Centralized Configuration** - All option defaults in 20 - `modules/options.nix` (single source of truth) 21 - 🔄 **DRY Principles** - Zero duplication; the NixOS module system handles everything 22 - 🎯 **Easy Customization** - Change any default in one file, applies everywhere 23 - 📦 **Multi-System** - Unified config for NixOS and macOS 24 - 🏠 **Unified Home Manager** - Same shell, git, SSH config across all systems 25 - 🔐 **Secrets Management** - Encrypted secrets with sops-nix 26 - 🛠️ **Rust Tools** - `health-check`, `flake-bump`, `gen-diff` maintenance utilities 19 + ✨ **Centralized Configuration** — All option defaults in `modules/options.nix` (single source of truth) 20 + 🔄 **DRY Principles** — Zero duplication; the NixOS module system handles everything 21 + 🎯 **Easy Customization** — Change any default in one file, applies everywhere 22 + 📦 **Multi-System** — Unified config for NixOS and macOS 23 + 🏠 **Unified Home Manager** — Same shell, git, SSH config across all systems 24 + 🔐 **Secrets Management** — Encrypted secrets with sops-nix 25 + 🗺️ **Infrastructure Diagrams** — Auto-generated topology SVGs via nix-topology 26 + 🛠️ **Rust Tools** — `health-check`, `flake-bump`, `gen-diff` maintenance utilities 27 27 28 28 ## Managed Systems 29 29 30 - ### macOS (nix-darwin) - PRIMARY 31 - 32 - - **macmini** - Apple Silicon Mac Mini (M2, 16 GB) — Main daily driver 30 + ### macOS (nix-darwin) — PRIMARY 33 31 34 - ### Linux (NixOS) - SECONDARY 32 + - **macmini** — Apple Silicon Mac Mini (M2, 16 GB) — Main daily driver 35 33 36 - - **laptop** - Dell Inspiron 3501 with KDE Plasma 6 — Secondary workstation 37 - - **server** - Minimal headless server — Bluesky PDS, Forgejo, 38 - Nextcloud, Cloudflare tunnel + hardened security 34 + ### Linux (NixOS) — SECONDARY 39 35 40 - ## Repository Structure 41 - 42 - ```text 43 - . 44 - ├── flake.nix # Main flake — defines all hosts 45 - ├── flake.lock # Locked dependency versions 46 - 47 - ├── hosts/ # Host-specific configurations 48 - │ ├── laptop/ # Dell Inspiron 3501 (NixOS + KDE Plasma 6) 49 - │ ├── server/ # Headless server (NixOS) 50 - │ └── macmini/ # Mac Mini M2 (nix-darwin) 51 - 52 - ├── modules/ # Reusable system modules 53 - │ ├── options.nix # ⭐ All option declarations + defaults 54 - │ ├── common.nix # Base NixOS settings (gc, auto-upgrade, etc.) 55 - │ ├── desktop.nix # KDE Plasma 6 + SDDM 56 - │ ├── gaming.nix # Steam + Gamemode 57 - │ ├── packages.nix # Desktop system packages 58 - │ ├── services.nix # Printing, Bluetooth, etc. 59 - │ ├── users.nix # User account configuration 60 - │ ├── caddy.nix # Caddy web server 61 - │ ├── pds.nix # Bluesky ATProto PDS 62 - │ ├── pds-landing/ # PDS landing page assets 63 - │ ├── forgejo.nix # Forgejo git forge 64 - │ ├── nextcloud.nix # Nextcloud instance 65 - │ ├── cloudflare-tunnel.nix # Cloudflare tunnel (outbound-only) 66 - │ ├── ssh-keys.nix # Public key registry for all hosts 67 - │ ├── server/ # Headless server sub-modules 68 - │ │ ├── firewall.nix 69 - │ │ ├── intrusion.nix # fail2ban 70 - │ │ ├── ssh.nix # sshd hardening 71 - │ │ ├── hardware-health.nix 72 - │ │ ├── maintenance.nix 73 - │ │ ├── packages.nix 74 - │ │ ├── services.nix 75 - │ │ └── disable-noise.nix 76 - │ └── darwin/ # macOS-specific modules 77 - │ ├── common.nix 78 - │ ├── homebrew.nix 79 - │ ├── packages.nix 80 - │ └── system.nix 81 - 82 - ├── profiles/ # Reusable configuration profiles 83 - │ ├── server-base.nix # Base server config 84 - │ └── server-hardened.nix # Security hardening 85 - 86 - ├── home/ # Home Manager (unified across all hosts) 87 - │ ├── default.nix # Main entry point 88 - │ ├── scripts/ # User scripts (update-all, verify-ssh-external, ...) 89 - │ └── programs/ # git, zsh, ssh, vscode, kde, ghostty, ... 90 - 91 - ├── settings/ # Platform-specific declarative settings 92 - │ ├── darwin/ # macOS system.defaults (Dock, Finder, trackpad, etc.) 93 - │ └── plasma/ # KDE Plasma declarative settings 94 - 95 - ├── secrets/ # sops-encrypted secrets (safe to commit) 96 - │ ├── setup.sh # Key management helper 97 - │ └── *.env / *.json / ... # Encrypted secret files 98 - 99 - ├── hooks/ 100 - │ └── pre-commit # auto-format: nix, sh, rust, toml, md 101 - 102 - ├── tools/ # Rust maintenance tools 103 - │ └── src/bin/ # health-check, flake-bump, gen-diff, server-config 104 - └── wallpapers/ 105 - ``` 36 + - **laptop** — Dell Inspiron 3501 with KDE Plasma 6 — Secondary workstation 37 + - **server** — Minimal headless server — Bluesky PDS, Forgejo, Nextcloud, 38 + Immich, Jellyfin, Cloudflare tunnel + hardened security 106 39 107 40 ## Configuration Architecture 108 41 ··· 170 103 sudo darwin-rebuild switch --flake .#macmini 171 104 ``` 172 105 106 + ## Infrastructure Diagrams 107 + 108 + Uses [nix-topology](https://github.com/oddlama/nix-topology) to automatically 109 + generate SVG diagrams of the infrastructure from the NixOS configurations. 110 + Physical connections and networks that can't be inferred automatically are 111 + defined in `topology.nix`. 112 + 113 + **Render the diagrams:** 114 + 115 + ```bash 116 + nix build .#topology.x86_64-linux.config.output 117 + # SVGs are in ./result/ 118 + ``` 119 + 120 + This produces two diagrams: 121 + 122 + - `main.svg` — physical host/interface layout 123 + - `network.svg` — network-centric view showing which hosts share which networks 124 + 125 + **Updating topology:** 126 + 127 + Edit `topology.nix` to reflect physical changes (new cables, new networks, etc.). 128 + Service and interface information is extracted automatically from the NixOS configs. 129 + 173 130 ## Customization 174 131 175 132 **All defaults live in `modules/options.nix`** — one option block per domain. 176 133 177 134 ```bash 178 135 # Examples of what to edit 179 - nano modules/options.nix # Username, timezone, packages, themes, etc. 180 - nano hosts/laptop/default.nix # Enable gaming, desktop mode, etc. 181 - nano hosts/server/default.nix # Enable server services 182 - nano settings/darwin/default.nix # macOS Dock, Finder, trackpad 183 - nano settings/plasma/default.nix # KDE Plasma layout and behaviour 136 + nano modules/options.nix # Username, timezone, packages, themes, etc. 137 + nano hosts/laptop/default.nix # Enable gaming, desktop mode, etc. 138 + nano hosts/server/default.nix # Enable server services 139 + nano topology.nix # Physical network connections 140 + nano settings/darwin/default.nix # macOS Dock, Finder, trackpad 141 + nano settings/plasma/default.nix # KDE Plasma layout and behaviour 184 142 ``` 185 143 186 144 See [`docs/settings.md`](docs/settings.md) for the full guide and ··· 192 150 ### Health Check (Recommended Before Building) 193 151 194 152 ```bash 195 - # Compile the tools (one-time) 196 - nix run .#tools -- --help 197 - 198 - # Run health check 199 - tools/target/release/health-check 200 - 201 - # Or use the shell alias 202 153 health-check 203 154 ``` 204 155 ··· 206 157 207 158 ```bash 208 159 nix flake update 209 - # Then rebuild 210 - sudo nixos-rebuild switch --flake .#laptop 211 - # or 212 - nix run .#tools -- flake-bump 160 + # or selectively 161 + flake-bump 213 162 ``` 214 163 215 164 ### Garbage Collection 216 165 217 166 ```bash 218 - # Runs automatically weekly on NixOS (configured in modules/common.nix) 219 - sudo nix-collect-garbage -d 220 - 221 - # Or use the alias 167 + # Runs automatically weekly (configured in modules/common.nix) 222 168 cleanup 223 169 ``` 224 170 ··· 240 186 1. Create `hosts/YOUR-HOSTNAME/default.nix` 241 187 2. Generate hardware config: `nixos-generate-config --show-hardware-config` 242 188 3. Add entry to `flake.nix` → `nixosConfigurations` 243 - 4. Build: `sudo nixos-rebuild switch --flake .#YOUR-HOSTNAME` 189 + 4. Add the host's interfaces/connections to `topology.nix` 190 + 5. Build: `sudo nixos-rebuild switch --flake .#YOUR-HOSTNAME` 244 191 245 192 ## Inputs 246 193 ··· 250 197 | [home-manager][home-manager] | release-25.11 | 251 198 | [nix-darwin][nix-darwin] | nix-darwin-25.11 | 252 199 | [sops-nix][sops-nix] | latest | 200 + | [nix-topology][nix-topology] | latest | 253 201 | [plasma-manager][plasma-manager] | latest | 202 + | [catppuccin][catppuccin] | latest | 203 + | [nix-vscode-extensions][nix-vscode-extensions] | latest | 204 + | [mac-app-util][mac-app-util] | latest | 254 205 255 206 [nixpkgs]: https://github.com/NixOS/nixpkgs 256 207 [home-manager]: https://github.com/nix-community/home-manager 257 208 [nix-darwin]: https://github.com/LnL7/nix-darwin 258 209 [sops-nix]: https://github.com/Mic92/sops-nix 210 + [nix-topology]: https://github.com/oddlama/nix-topology 259 211 [plasma-manager]: https://github.com/nix-community/plasma-manager 212 + [catppuccin]: https://github.com/catppuccin/nix 213 + [nix-vscode-extensions]: https://github.com/nix-community/nix-vscode-extensions 214 + [mac-app-util]: https://github.com/hraban/mac-app-util 260 215 261 216 ## Unified Configuration Benefits 262 217 ··· 288 243 ### Host Management 289 244 290 245 - [`docs/hosts.md`](docs/hosts.md) — hosts documentation index 291 - - [`docs/hosts-overview.md`](docs/hosts-overview.md) — complete 292 - comparison of all three hosts 293 - - [`docs/hosts-modification.md`](docs/hosts-modification.md) — 294 - how to modify and add hosts 295 - - [`docs/hosts-laptop.md`](docs/hosts-laptop.md) — Dell Inspiron 296 - 3501 (NixOS + KDE Plasma 6) 246 + - [`docs/hosts-overview.md`](docs/hosts-overview.md) — complete comparison of all three hosts 247 + - [`docs/hosts-modification.md`](docs/hosts-modification.md) — how to modify and add hosts 248 + - [`docs/hosts-laptop.md`](docs/hosts-laptop.md) — Dell Inspiron 3501 (NixOS + KDE Plasma 6) 297 249 - [`docs/hosts-server.md`](docs/hosts-server.md) — headless server setup 298 250 - [`docs/hosts-macmini.md`](docs/hosts-macmini.md) — macOS with nix-darwin 299 251 - [`docs/TAILSCALE-SSH.md`](docs/TAILSCALE-SSH.md) — inter-host SSH over Tailscale ··· 301 253 ### Settings Management 302 254 303 255 - [`docs/settings.md`](docs/settings.md) — settings overview 304 - - [`docs/settings-structure.md`](docs/settings-structure.md) — 305 - why the config is modular 256 + - [`docs/settings-structure.md`](docs/settings-structure.md) — why the config is modular 306 257 - [`docs/secrets.md`](docs/secrets.md) — secrets management
+22
flake.nix
··· 19 19 inputs.nixpkgs.follows = "nixpkgs"; 20 20 }; 21 21 22 + nix-topology = { 23 + url = "github:oddlama/nix-topology"; 24 + inputs.nixpkgs.follows = "nixpkgs"; 25 + }; 26 + 22 27 nix-vscode-extensions = { 23 28 url = "github:nix-community/nix-vscode-extensions"; 24 29 inputs.nixpkgs.follows = "nixpkgs"; ··· 45 50 home-manager, 46 51 nix-darwin, 47 52 sops-nix, 53 + nix-topology, 48 54 nix-vscode-extensions, 49 55 catppuccin, 50 56 mac-app-util, ··· 63 69 ./modules/options.nix 64 70 ./modules/common.nix 65 71 sops-nix.nixosModules.sops 72 + nix-topology.nixosModules.default 66 73 home-manager.nixosModules.home-manager 67 74 { 68 75 nixpkgs.config.allowUnfree = true; ··· 109 116 110 117 forAllSystems = 111 118 f: nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ] (system: f system); 119 + 120 + # Package set with the nix-topology overlay — required to build the topology output. 121 + topologyPkgs = import nixpkgs { 122 + system = "x86_64-linux"; 123 + overlays = [ nix-topology.overlays.default ]; 124 + }; 112 125 in 113 126 { 114 127 formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixfmt-rfc-style); 128 + 129 + # Render infrastructure diagrams: nix build .#topology.x86_64-linux.config.output 130 + topology.x86_64-linux = import nix-topology { 131 + pkgs = topologyPkgs; 132 + modules = [ 133 + ./topology.nix 134 + { nixosConfigurations = self.nixosConfigurations; } 135 + ]; 136 + }; 115 137 116 138 nixosConfigurations = { 117 139 laptop = nixpkgs.lib.nixosSystem {
+86
topology.nix
··· 1 + ############################################################################## 2 + # nix-topology — global infrastructure topology definition. 3 + # 4 + # This file defines the physical connections, networks, and external devices 5 + # that can't be inferred automatically from the NixOS configurations. 6 + # 7 + # Render: 8 + # nix build .#topology.x86_64-linux.config.output 9 + # # SVGs are in ./result/ 10 + # 11 + # Docs: https://oddlama.github.io/nix-topology 12 + ############################################################################## 13 + { config, lib, ... }: 14 + { 15 + # ── External devices ─────────────────────────────────────────────────────── 16 + nodes.internet = { 17 + name = "Internet"; 18 + icon = "services.cloudflare"; 19 + interfaces.tunnel = { 20 + name = "CF Tunnel"; 21 + network = "cloudflare"; 22 + }; 23 + }; 24 + 25 + nodes.router = { 26 + name = "Router"; 27 + deviceType = "router"; 28 + interfaces.wan = { 29 + name = "WAN"; 30 + network = "wan"; 31 + }; 32 + interfaces.lan = { 33 + name = "LAN"; 34 + network = "home"; 35 + }; 36 + }; 37 + 38 + # ── Networks ─────────────────────────────────────────────────────────────── 39 + networks.home = { 40 + name = "Home Network"; 41 + cidrv4 = "192.168.1.0/24"; 42 + }; 43 + 44 + networks.cloudflare = { 45 + name = "Cloudflare Tunnel"; 46 + style.color = "#f48120"; 47 + }; 48 + 49 + networks.tailscale = { 50 + name = "Tailnet"; 51 + cidrv4 = "100.64.0.0/10"; 52 + style.color = "#4a9eed"; 53 + }; 54 + 55 + # ── Physical connections ─────────────────────────────────────────────────── 56 + # Router LAN → each host's primary ethernet/wifi interface. 57 + nodes.router.interfaces.lan.physicalConnections = [ 58 + { 59 + node = "server"; 60 + interface = "eth0"; 61 + } 62 + { 63 + node = "laptop"; 64 + interface = "wlan0"; 65 + } 66 + ]; 67 + 68 + # ── Host network assignments ─────────────────────────────────────────────── 69 + nodes.server.interfaces.eth0.network = "home"; 70 + nodes.server.interfaces.tailscale0.network = "tailscale"; 71 + 72 + nodes.laptop.interfaces.wlan0.network = "home"; 73 + nodes.laptop.interfaces.tailscale0.network = "tailscale"; 74 + 75 + # ── Cloudflare tunnel (logical, outbound-only from server) ───────────────── 76 + nodes.server.interfaces.cf-tunnel = { 77 + name = "CF Tunnel"; 78 + network = "cloudflare"; 79 + physicalConnections = [ 80 + { 81 + node = "internet"; 82 + interface = "tunnel"; 83 + } 84 + ]; 85 + }; 86 + }