- Nix 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks failed
mirror-to-github.yaml / idk anymore, be blessed (push) Failing after 0s
|
||
| .gitea/workflows | ||
| home | ||
| overlays | ||
| system | ||
| .gitignore | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
nixos-config
My NixOS flake configuration for a single x86_64 desktop. System and Home Manager are managed together.
Stack
| Layer | Tool |
|---|---|
| Window manager | Hyprland |
| Shell | Zsh + Starship |
| Terminal | Kitty |
| Theme engine | Stylix (Tokyo Night Storm) |
| Secure boot | Lanzaboote |
| Display manager | greetd + tuigreet |
| Audio | PipeWire |
| Graphics | AMD |
Structure
flake.nix # Inputs, system + home-manager wired as one NixOS module
system/ # NixOS system configuration
configuration.nix # Hardware, users, core services
packages.nix # System-wide packages
*.nix # Feature modules (audio, fonts, network, GPU…)
home/ # Home Manager configuration
home.nix # Base home settings, Stylix
packages.nix # User packages
*.nix # App/tool modules (Hyprland, Zsh, VSCode, Kitty…)
Usage
Rebuild system (handles both NixOS and Home Manager in one shot):
sudo nixos-rebuild switch --flake .#nixos
Flakes only see git-tracked files. A newly added
*.nixmust begit added beforenixos-rebuild, or eval fails withPath '…' in the repository is not tracked by Git.
Remote desktop (Sunshine + Moonlight)
Streams the live Hyprland session to the MacBook over the homelab road-warrior
WireGuard VPN. Config: system/sunshine.nix.
xrdp and gnome-remote-desktop don't fit here — xrdp spawns a throwaway X session instead of attaching to the real one, and gnome-remote-desktop needs GNOME. Sunshine captures the live session via DRM/KMS and hardware-encodes on the amdgpu through VA-API.
First-time setup
sudo nixos-rebuild switch --flake .#nixos, then log back into Hyprland so thesunshineuser service starts.- Immediately open
https://10.29.90.100:47990and set the admin username/password. Self-signed cert, so accept the browser warning. ⚠️ Sunshine ships with no credentials — the first person to load that page claims the host. Don't leave the gap open. - On the Mac:
brew install --cask moonlight. - In Moonlight, add the host manually by IP (
10.29.90.100). Auto-discovery is mDNS and does not cross the VPN — the machine will never appear on its own. - Moonlight shows a PIN → enter it in the web UI under PIN.
Day to day
Connect to the VPN first, then open Moonlight. Start around 1080p60 at 10–20 Mbps: the stream flows desktop → OPNsense → walle → Mac, so it consumes home upload bandwidth through the CGNAT-bypass tunnel. The local 1440p/240Hz setup is not going over that link regardless of settings.
Gotchas
- Black screen after a successful pair = capture failed, not networking.
Nearly always
capSysAdminbeing off, orsunshine.servicehaving started beforeWAYLAND_DISPLAYreached the systemd user environment. Thesystemctl --user restart sunshine.serviceinhome/hyprland.nix'sexec-onceexists for the second case. Check withsystemctl --user status sunshineandjournalctl --user -u sunshine -b. - Nothing to attach to after a reboot. Sunshine captures an existing
session, and tuigreet has no autologin — a reboot while travelling parks the
box at the greeter. SSH still works but can't start a graphical session. Fix is
the commented-out
initial_sessionblock insystem/desktop.nix(boot to a locked Hyprland session); read the tradeoff there before enabling. - Moonlight won't auto-discover over the VPN. mDNS is link-local. Always add the host by IP.
openFirewall = trueopens on every interface. NixOS has no per-interface scoping for it. Exposure is PC-PERSONAL + VPN clients; nothing forwards these ports from the WAN, and it should stay that way — Sunshine's web UI can launch processes on this machine.capSysAdmin = trueis a broad capability, close to root, on the sunshine wrapper binary. It's the cost of Wayland KMS capture without a portal path.
Network prerequisite
The desktop is 10.29.90.100 on PC-PERSONAL (10.29.88.0/22). That subnet must
be in the VPN client's AllowedIPs and have a matching WGVPN pass rule on
OPNsense — see docs/roadwarrior-vpn.md in the homelab repo. Adding a subnet to
AllowedIPs needs no re-keying; edit the tunnel and reconnect.
Lighter fallback
For editing a config file over a bad hotel link, plain ssh already works (the
box runs services.openssh), and ssh -X forwards individual X11 apps if the Mac
has XQuartz. wayvnc is the middle ground if Sunshine is ever too heavy — wlroots
native, software-encoded, one TCP port.