- Nix 98.6%
- Shell 1.4%
freecad is the same 1.1.1 on both channels, but on unstable its closure (vtk/pdal → gdal 3.13) fell out of cache and forces a local vtk+freecad compile. Stable's 1.1.1 links against gdal 3.12.4/pdal 2.9.3, is fully cached (fetch-only), and coexists with the unstable deps in the store. Consumed via the nixpkgs-stable already in home-manager extraSpecialArgs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y8uSrQMxWxTqBMF8s4b5KK |
||
|---|---|---|
| archive/strider | ||
| home | ||
| hosts | ||
| scripts | ||
| secrets | ||
| .gitignore | ||
| .sops.yaml | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
nixos-config
I'm Greg Helding. You can find me at helding.net, on GitHub at github.com/gthelding, and on Forgejo at forgejo.gth.sh/greg.
This is my personal NixOS flake for six machines (plus a custom installer ISO), with shared Home Manager modules and per-host user profiles (greg and w9gth). Welcome, and thanks for stopping by - feel free to explore the layout, borrow ideas, and adapt anything useful for your own setup.
This README is a tour, not a step-by-step guide. It is intended as "here is my flake, read it and take what you like." Comments welcome. Keep roasting to a minimum.
Quick links: Hosts | What this repo manages | Repository layout | Command snippets | Audio | Molly tuning | Hyprland desktop | Shell, terminal & prompt | Distrobox | Flake input note
Hosts
| Host | Hardware | Role | User / Profile |
|---|---|---|---|
molly |
ThinkPad X1 Gen 11 | Daily-driver laptop (Wayland + Hyprland) | greg (home/greg/molly.nix) |
wintermute |
System76 Thelio desktop (AMD GPU) | Workstation (Plasma 6) | greg (home/greg/default.nix) |
hosaka |
Geekom mini-PC | Ham-shack desktop (Wayland + Hyprland) | w9gth (home/w9gth/default.nix) |
matrix |
Proxmox VM | Matrix Synapse homeserver | Headless server (no Home Manager) |
social |
Proxmox VM | Mastodon server (gth.social) |
Headless server (no Home Manager) |
webtop |
Proxmox VM | Remote desktop (Guacamole/xrdp/XFCE) | Headless server (no Home Manager) |
There is also an iso output — a custom installer image with this flake baked
in, built via nix build .#nixosConfigurations.iso.config.system.build.isoImage.
What this repo manages
- NixOS system configuration per host under
hosts/ - Shared and user-specific Home Manager modules under
home/ - Host-aware user services (for example, backup timers on
wintermute) - Headless service hosts for Matrix Synapse and Mastodon on
nixpkgs-stable - Scripts synced into
~/.local/binvia Home Manager - Per-host theming for terminal apps — rmpc, btop, and Neovim each pick a
colorscheme by host (Neovim comes from the external
nvf-configflake vialib.mkNvim "<theme>")
Repository layout
flake.nix Flake entrypoint and host definitions
hosts/
common-base.nix Shared baseline across all hosts
common-desktop.nix Shared desktop stack for GUI hosts
common-server.nix Shared baseline for the stable-branch servers
quiet-boot.nix Quiet graphical boot (plymouth) for desktop hosts
molly/ Laptop system config + hardware (Wayland + Hyprland)
thyx-theme.conf Custom SDDM thyx greeter theme (cyberpunk)
wintermute/ Workstation system config + hardware
hosaka/ Ham-shack desktop config + hardware
matrix/ Matrix Synapse server config + hardware
social/ Mastodon server config + hardware
webtop/ Remote-desktop server config + hardware
iso/ Custom installer ISO config
secrets/
matrix/ sops-encrypted Synapse secrets
social/ sops-encrypted Mastodon secrets
webtop/ sops-encrypted remote-desktop secrets
home/
greg/ Home Manager profile for user greg (wintermute, molly)
default.nix Entry point (wintermute, Plasma 6)
molly.nix Entry point (Wayland + Hyprland laptop)
desktop/ molly's Hyprland desktop layer (forked per host)
plasma.nix KDE Plasma 6 config
ntfy.nix ntfy desktop notifications
w9gth/ Home Manager profile for user w9gth (hosaka)
default.nix Entry point (Wayland + Hyprland)
desktop/ hosaka's Hyprland desktop layer (forked per host)
shared/
bash.nix Shell + starship config (parameterized per host)
ghostty.nix Parameterized ghostty terminal config
ghostty-shaders.nix Pinned ghostty-shaders fetch (shared by ghostty/rmpc)
rmpc.nix Parameterized rmpc config + ghostty wrapper (per host)
fastfetch.nix Parameterized fastfetch config (per-host logo)
gdb.nix GDB defaults (Intel syntax)
packages/ User package sets (cli, desktop, dev, media, etc.)
starship*.toml Starship prompt themes (selected per host)
scripts/ Helper scripts (backups, git helpers, rsync exclude)
Command snippets
Build a host config without switching:
sudo nixos-rebuild build --flake .#molly
sudo nixos-rebuild build --flake .#wintermute
sudo nixos-rebuild build --flake .#hosaka
sudo nixos-rebuild build --flake .#matrix
sudo nixos-rebuild build --flake .#social
sudo nixos-rebuild build --flake .#webtop
Apply configuration to the current host:
sudo nixos-rebuild switch --flake .#molly
sudo nixos-rebuild switch --flake .#wintermute
sudo nixos-rebuild switch --flake .#hosaka
sudo nixos-rebuild switch --flake .#matrix
sudo nixos-rebuild switch --flake .#social
sudo nixos-rebuild switch --flake .#webtop
Update flake lockfile:
nix flake update
Note:
matrix,social, andwebtoptracknixpkgs-stable(26.05) rather than unstable and have no Home Manager user environment - they are headless servers only. Secrets are managed viasops-nix; encrypted files live undersecrets/and are decrypted at runtime from each host's local key material.
socialruns Mastodon atgth.socialwith a manual nginx config (SSL is terminated by an external reverse proxy). SMTP credentials are sourced from encrypted secrets.
Audio
PipeWire is enabled in hosts/common-base.nix for all desktop hosts
(including molly and wintermute). Host-specific audio tuning lives in
each host's configuration.nix rather than the shared module:
wintermutecarries a low-latency profile (92-low-latency, fixed 512-quantum at 48 kHz) and a wireplumber rule (99-no-suspend) that prevents ALSA nodes from suspending. This suits a workstation with always-connected speakers and recording use.mollyuses default PipeWire behavior: dynamic quantum and normal node suspend, which is friendlier to laptop battery life.
wintermute also runs voxtype (Vulkan-accelerated TTS) as a system
service — the package and NixOS module are pulled from the voxtype flake
input.
Molly (X1 Gen 11) tuning
molly is the machine formerly known as strider, reborn on an XFS root
(no ZFS, so linuxPackages_latest is never blocked) running Wayland +
Hyprland instead of Plasma. The retired strider config is kept for reference under
archive/strider/. In addition to the shared baseline, molly applies a
few laptop-specific tweaks in hosts/molly/configuration.nix:
-
VA-API:
LIBVA_DRIVER_NAME=iHDis exported so mpv, OBS, and other VA-API consumers use the modern Intel Media Driver instead of falling back to legacyi965. -
TLP charge thresholds: paired hysteresis with
START_CHARGE_THRESH_BAT0=75andSTOP_CHARGE_THRESH_BAT0=80to prevent constant micro-charging at 100%. -
TLP power tuning on battery:
RUNTIME_PM_ON_BAT=autoandPCIE_ASPM_ON_BAT=powersupersavefor additional runtime PM and deeper PCIe link power savings. -
thermald plus
power-profiles-daemondisabled, so TLP owns power management without contention. -
SDDM Thyx greeter: A custom cyberpunk theme replaces the upstream
blushpreset — Hurmit Nerd Font (matching waybar), a teal/purple/hot-pink palette (#00f5d4/#7b61ff/#ff10f0), and a looping video background. The theme lives athosts/molly/thyx-theme.confand is baked into thethyxMollypackage derivation inflake.nix.
Quick post-switch verification on molly:
vainfo # should show iHD driver
tlp-stat -b # should show START=75, STOP=80
pw-metadata -n settings # quantum should not be pinned to 512
Hyprland desktop (molly, hosaka)
Each tiling-WM host has its own desktop layer — molly's at
home/greg/desktop/, hosaka's at home/w9gth/desktop/ — forked from a
formerly-shared module so the two hosts can diverge freely in theming, apps,
and window behavior (the WM package itself comes from the system via
programs.hyprland.enable). Each default.nix imports its hyprland.nix
(compositor settings) plus companion desktop modules, together bundling the
whole Wayland desktop; the copies started identical, so the following
describes both:
- Waybar with custom scripts (now-playing media, a rotating
public/private/Tailscale IP widget, wttr.in weather) alongside native
bluetooth,idle-inhibitor, and a rofi power menu. All glyphs are decoded from hex codepoints so they survive in-file rather than being stripped. - Screenshots via
grim/slurppiped tosattyfor annotation, with a rofi action menu ($mod+S) and Print-key shortcuts. - Named scratchpads — drop-down ghostty (
$mod+`), rmpc music ($mod+M), Discord ($mod+D), and Obsidian ($mod+O). Each toggles a per-app Hyprland special workspace, launching on first use and floating centered over the current workspace. Placement uses inline exec rules plus a class-tracking helper that re-parks the window — which is what makes Electron apps (Discord/Obsidian, whose splash window otherwise steals the rule) land correctly. Sizes are a percentage of the focused monitor's logical resolution, so they scale across molly (1×) and hosaka's 4K (1.5×). - hyprlock + hypridle for lock/idle, cliphist clipboard
history, hyprpaper/waypaper wallpapers, and a
$mod+/keybind cheatsheet kept in sync with the bind list.
$mod+M launches rmpc inside ghostty with a dedicated rmpc.conf (see
below), so the music scratchpad carries its own terminal theming.
Shell, terminal & prompt
The interactive look-and-feel is factored into small parameterized Home
Manager modules under home/shared/, each imported per user profile with
host-specific arguments (the same idiom as bash.nix). The underlying
packages all come from the shared CLI package set, so these modules only
own the config:
bash.nix— shell config plus the starship prompt. ThestarshipThemeargument selects a theme file:starship.toml(wintermute),starship-cyber-powerline.toml(molly's neon powerline), andstarship-pastel-powerline.toml(hosaka).ghostty.nix—programs.ghosttyconfig taking{ theme, fontFamily?, fontSize?, opacity?, shaders?, extraSettings? }. Custom GLSL shaders (e.g.cursor_blaze.glsl) are pulled from the pinnedhackr-sh/ghostty-shaderscheckout, factored intoghostty-shaders.nixso the main config and the rmpc wrapper share one store path.ghostty +list-themeslists the 460+ built-in themes.rmpc.nix— parameterized{ variant }module (wintermute|molly|hosaka) owning rmpc's config: a per-host ghostty terminal wrapper (ghostty/rmpc.conf), a sharedconfig.ronbase with its theme line and a@queue_pane@placeholder swapped per variant (so keybinds/mpd/cava stay shared), and a per-host TUI theme.wintermutekeeps the gruvbox/CRT look (album art as a column in the Queue tab);mollyandhosakashare a cyberpunk look (Hurmit font, no shader, midnight-blue palette, full-width Queue with album art beside the cava visualizer) — hosaka's files are seeded copies of molly's and can diverge for its 4K panel. The wrapper.conffiles are plain ghostty configs with a@shaders@placeholder substituted to the pinned shader path at build.fastfetch.nix— takes{ configFile, imagesDir? }and installs the XDG config (and optional logo images). Per-host configs live inhome/shared/packages/fastfetch/config-<host>.jsonc; the customcyber-fetch.pnglogo is shared via theimages/dir.
Distrobox
Distrobox containers are configured in hosts/common-base.nix with access to
Nix-installed executables. Three things make this work:
-
Bind mounts expose the Nix store and user profile symlinks into every container (read-only):
/nix/store/etc/profiles/per-user/etc/static/profiles/per-user
-
An init hook creates
/etc/profile.d/nix-path.shinside the container on first entry, which adds/etc/profiles/per-user/$USER/bintoPATH. This is necessary because NixOS normally setsPATHvia/etc/set-environmentduring login, and that mechanism doesn't exist inside the container. -
Podman is the container runtime (
virtualisation.podman).
Flake input note
The Neovim config inputs (nvf-config, nvf-config-stable) point at a
private Forgejo mirror over SSH (forgejo.gth.sh). All other inputs are
public GitHub sources. If you're not on that network, replace those two
URLs with the upstream before running nix flake update.