- Nix 86.8%
- Shell 13.2%
| assets | ||
| home | ||
| hosts | ||
| scripts | ||
| secrets | ||
| .gitignore | ||
| .sops.yaml | ||
| 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, with shared Home Manager modules and per-host user profiles (greg, case, 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 | Strider tuning | Distrobox | Flake input note
Hosts
| Host | Hardware | Role | User / Profile |
|---|---|---|---|
strider |
ThinkPad X1 Carbon Gen 11 | Daily-driver laptop | greg (home/greg/default.nix) |
wintermute |
System76 Thelio desktop (AMD GPU) | Workstation | greg (home/greg/default.nix) |
ono-sendai |
ThinkPad T490 | TTY-only writerdeck | case (home/case/default.nix) |
hosaka |
Geekom mini-PC | Ham-shack desktop (XFCE + i3) | 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) |
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
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
strider/ Laptop system config + hardware
wintermute/ Workstation system config + hardware
ono-sendai/ TTY-only writerdeck config + hardware
hosaka/ Ham-shack desktop config + hardware
matrix/ Matrix Synapse server config + hardware
social/ Mastodon server config + hardware
secrets/
matrix/ sops-encrypted Synapse secrets
social/ sops-encrypted Mastodon secrets
home/
greg/ Home Manager profile for user greg (strider, wintermute)
default.nix Entry point
plasma.nix KDE Plasma 6 config
ntfy.nix ntfy desktop notifications
w9gth/ Home Manager profile for user w9gth (hosaka)
default.nix Entry point
i3-jag.nix Ported justaguylinux i3 dotfiles
case/ Home Manager profile for user case (ono-sendai)
default.nix Minimal TTY writerdeck profile
shared/
bash.nix Shell configuration
gdb.nix GDB defaults (Intel syntax)
packages/ User package sets (cli, desktop, dev, media, etc.)
starship.toml Starship prompt theme
scripts/ Helper scripts (backups, git helpers, rsync exclude)
assets/ Misc assets used by the setup
Command snippets
Build a host config without switching:
sudo nixos-rebuild build --flake .#strider
sudo nixos-rebuild build --flake .#wintermute
sudo nixos-rebuild build --flake .#ono-sendai
sudo nixos-rebuild build --flake .#hosaka
sudo nixos-rebuild build --flake .#matrix
sudo nixos-rebuild build --flake .#social
Apply configuration to the current host:
sudo nixos-rebuild switch --flake .#strider
sudo nixos-rebuild switch --flake .#wintermute
sudo nixos-rebuild switch --flake .#ono-sendai
sudo nixos-rebuild switch --flake .#hosaka
sudo nixos-rebuild switch --flake .#matrix
sudo nixos-rebuild switch --flake .#social
Update flake lockfile:
nix flake update
Note:
matrixandsocialtracknixpkgs-stable(25.11) 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-desktop.nix for the desktop hosts
(strider and wintermute). Host-specific audio tuning lives in each
host's configuration.nix rather than the shared desktop 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.strideruses default PipeWire behavior: dynamic quantum and normal node suspend, which is friendlier to laptop battery life.
Strider (X1 Carbon Gen 11) tuning
In addition to the shared desktop config, strider applies a few
laptop-specific tweaks in hosts/strider/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. - ZFS auto-snapshot bootstrap: a oneshot unit
(
zfs-auto-snapshot-init) setscom.sun:auto-snapshotproperties onrpooldatasets at boot.
Quick post-switch verification on strider:
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
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
Inputs currently point at private Forgejo mirrors over SSH (see flake.nix).
If you are not on that network/account, replace input URLs with upstream sources before running updates.