- Nix 78.3%
- Lua 20.4%
- CSS 1.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| dotfiles | ||
| hosts | ||
| modules | ||
| overlays | ||
| secrets | ||
| .gitignore | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
NixOS configuration
Declarative setup for radiator and laptop
Hosts · Architecture · Packages · Secrets · Rebuilding
✦ What this is
A personal, flake-based NixOS configuration for a desktop and laptop. Shared behavior is composed from focused modules, while hardware and machine-specific decisions remain with their host.
Highlights
- Hyprland configured in Lua on both workstations.
- Reusable profiles, features and independently importable package groups.
- User environments and dotfiles managed through Home Manager.
- SSH and WireGuard private keys encrypted with Agenix.
- NVIDIA desktop and Intel laptop configuration maintained in one flake.
| Layer | Stack |
|---|---|
| OS | NixOS unstable · Lix · Flakes |
| Desktop | Hyprland · Lua · UWSM |
| User environment | Home Manager |
| Shell and terminal | Zsh · Ghostty |
| Editor | Neovim · LazyVim |
| Secrets | Agenix |
| Networking | WireGuard · nftables · NetworkManager |
| Audio | PipeWire |
Design goals:
Declarative → Modular → Host-aware → Reproducible → Recoverable
🖥️ Hosts
| Host | User | Role | Desktop |
|---|---|---|---|
radiator |
blueguy |
NVIDIA desktop and primary workstation | Hyprland + Noctalia, Plasma fallback |
laptop |
etc |
Intel laptop and SSH client | Hyprland + Waybar/Rofi/Mako, Plasma fallback |
📁 Architecture
.
├── flake.nix
├── flake.lock
├── hosts/
│ ├── radiator/
│ │ ├── packages/
│ │ ├── audio.nix
│ │ ├── network.nix
│ │ ├── nixpkgs.nix
│ │ ├── secrets.nix
│ │ └── ...
│ ├── laptop/
│ │ ├── packages/
│ │ ├── audio.nix
│ │ ├── bluetooth.nix
│ │ ├── network.nix
│ │ ├── power.nix
│ │ ├── secrets.nix
│ │ └── ...
├── modules/
│ ├── nixos/
│ │ ├── core/
│ │ ├── profiles/
│ │ ├── features/
│ │ ├── packages/
│ │ ├── users/
│ │ ├── radiator/
│ │ ├── laptop/
│ └── home/
│ ├── base/
│ ├── radiator/
│ └── laptop/
├── dotfiles/
│ ├── common/
│ ├── radiator/
│ └── laptop/
├── secrets/
└── overlays/
Module ownership
core/contains flake-wide Nix and Home Manager integration.profiles/compose reusable capabilities into complete machine roles.features/enable one reusable system capability.packages/contain independently importable package categories.hosts/<name>/contains hardware, networking and configuration unique to one machine.modules/home/manages user programs and dotfiles.
A setting remains host-specific until another host needs it in the same form.
📦 Package model
The package configuration is layered:
base profile
└── shared CLI tools
workstation profile
├── base profile
├── reusable desktop features
└── shared package categories
host configuration
└── packages used only by that machine
Both current workstations import modules/nixos/profiles/workstation.nix. A future host can instead select individual categories:
{
imports = [
../../modules/nixos/profiles/base.nix
../../modules/nixos/packages/media.nix
../../modules/nixos/packages/development.nix
];
}
Desktop-only additions live under hosts/radiator/packages/. Laptop-only additions stay in hosts/laptop/packages/. Both are directories of per-category files; shared categories live in modules/nixos/packages/.
⌨️ Desktop workflow
Hyprland is configured in Lua on both workstations:
dotfiles/radiator/hypr/
├── hyprland.lua
├── binds.lua
└── hypridle.conf
dotfiles/laptop/hypr/
├── hyprland.lua
├── binds.lua
├── hypridle.conf
└── hyprlock.conf
Common bindings:
| Key | Action |
|---|---|
SUPER + Enter |
Terminal |
SUPER + E |
File manager |
SUPER + B |
Browser |
SUPER + Space |
Application launcher |
SUPER + Q |
Close window |
SUPER + L |
Lock session |
SUPER + 1…0 |
Change workspace |
SUPER + Shift + 1…0 |
Move window to workspace |
Print |
Region screenshot |
Repository changes managed by Home Manager are not live until a new generation is activated. After rebuilding, log out and back in when testing Hyprland startup changes.
🔐 Secrets
SSH identities and WireGuard private keys are encrypted with Agenix. Encrypted .age files can be committed; decrypted private keys must never be committed.
secrets/
├── secrets.nix
├── radiator/
│ ├── ssh-vps.age
│ └── wireguard-private-key.age
└── laptop/
├── ssh-radiator.age
├── ssh-vps.age
└── wireguard-private-key.age
Edit a secret from the secrets directory:
cd ~/nix/secrets
agenix -e laptop/ssh-vps.age
Agenix decrypts secrets using the host identity at /etc/ssh/ssh_host_ed25519_key. Preserve that key across a reinstall or re-encrypt the affected secrets for the new host public key.
Password hashes are still stored in the user modules and are the next secrets to migrate.
🚀 Rebuilding
Test a generation first:
cd ~/nix
sudo nixos-rebuild test --flake .#laptop
For radiator:
sudo nixos-rebuild test --flake .#radiator
If the test generation works:
sudo nixos-rebuild switch --flake .#laptop
Safe workflow:
edit
↓
nix flake check
↓
nixos-rebuild test
↓
verify the desktop, network and secrets
↓
nixos-rebuild switch
🧰 Useful commands
nix flake check
nix flake update
sudo nixos-rebuild test --flake .#laptop
sudo nixos-rebuild switch --flake .#laptop
sudo nixos-rebuild switch --rollback
nix-collect-garbage --delete-older-than 7d
The system also performs weekly garbage collection and automatically optimises the Nix store.
🧯 Recovery
Plasma is retained on both workstations as a fallback if Hyprland is broken. Select the Plasma session in SDDM, repair the configuration, then test another generation.
Rollback directly when necessary:
sudo nixos-rebuild switch --rollback
NixOS · Hyprland · Home Manager · Agenix
One repository for reproducible workstation and laptop configuration.