NixOS + Home Manager Configuration#
This repository contains my personal NixOS system configurations and Home Manager setup, managed via Nix flakes.
Overview#
This is a multi-host NixOS configuration using:
- Nix Flakes for reproducible builds and dependency management
- Home Manager for user environment configuration
- agenix for secrets management (age-based encryption)
- pre-commit-hooks for code quality
Hosts#
| Hostname | Purpose | Platform |
|---|---|---|
| odin | Main workstation with AMD GPU, Docker, Coder server, Valheim game server | x86_64-linux |
| misaki | NAS/Server with ZFS, Plex, Jellyfin, Immich, Nginx reverse proxy | x86_64-linux |
| shizuri | Steam/gaming machine with LXQt desktop and XRDP | x86_64-linux |
| edge | Solana validator node with Agave software | x86_64-linux |
| touma-wsl | WSL2 NixOS configuration | x86_64-linux |
| aleister-noah | macOS workstation (Home Manager only) | aarch64-darwin |
Repository Structure#
.
├── flake.nix # Main flake configuration defining all hosts
├── flake.lock # Lock file for reproducible builds
├── shell.nix # Development shell configuration
├── boot.nix # Bootloader configuration (shared)
├── common.nix # Common system settings (timezone, locale, gc, etc.)
├── users.nix # User definitions and SSH keys
├── services.nix # Shared service configurations
├── default-home.nix # Default Home Manager configuration
├── host-specific/ # Per-host configurations
│ ├── odin/
│ ├── misaki/
│ ├── shizuri/
│ ├── edge/
│ └── touma-wsl.nix
├── overlays/ # Package overlays
├── secrets/ # Encrypted secrets (agenix)
├── nvim/ # Neovim configuration
├── fish/ # Fish shell configuration
├── aerc/ # aerc email client configuration
├── scripts/ # Custom utility scripts
└── README.md # This file
Host Configuration Pattern#
Each host in host-specific/<hostname>/ follows a modular structure:
configuration.nix- Main entry point, imports other moduleshardware-configuration.nix- Auto-generated hardware configboot.nix- Bootloader and kernel settingsnetworking.nix- Network configurationpackages.nix- System packagesservices.nix- Service definitionsgui.nix- GUI/Desktop environment settings (where applicable)users.nix- Host-specific users and groups
Adding a New Host#
- Create a new directory under
host-specific/<hostname>/ - Copy the hardware configuration from the target machine:
nixos-generate-config --show-hardware-config > host-specific/<hostname>/hardware-configuration.nix - Create
configuration.niximporting necessary modules - Add the host to
flake.nixin thenixosConfigurationsoutput:nixosConfigurations.newhost = basicSystem { useUnstable = true; modules = [ ./host-specific/newhost/configuration.nix ]; }; - Build and switch:
sudo nixos-rebuild switch --flake .#newhost
Secrets Management#
Secrets are encrypted using agenix with age encryption.
- Secrets are stored in
secrets/with.ageextension - Public keys for hosts/users are defined in
secrets/secrets.nix - Each secret specifies which hosts/users can decrypt it
- Deployed secrets are owned by specific users/groups with appropriate permissions
To add a new secret:
- Add the secret file to
secrets/ - Define recipients in
secrets/secrets.nix - Encrypt:
agenix -e secrets/my-secret.age - Reference in your configuration via
age.secrets.my-secret
Development#
This repo includes a development shell with formatting and linting tools:
nix develop
Pre-commit hooks are configured to run automatically on commit:
nixfmt-rfc-style- Nix code formattingnil- Nix language server / linterluacheck- Lua linting (for Neovim config)
Key Features#
Overlays#
neovim.nix- Pins Neovim to specific versionlmstudio.nix- Local LLM GUI (AppImage wrapper)inetutils.nix- Version override for inetutils
Home Manager#
The default-home.nix provides a comprehensive development environment including:
- Neovim with extensive LSP and plugin configuration
- Fish shell with custom configuration
- Multiple language toolchains (Rust, Go, Clojure, Python, etc.)
- Git configuration with delta/difftastic
- Development tools (direnv, fzf, tmux, etc.)
Building#
NixOS System#
sudo nixos-rebuild switch --flake .#<hostname>
Home Manager (standalone)#
home-manager switch --flake .#noah
# or for macOS
home-manager switch --flake .#noah-aleister
Remote Builders#
shizuri and odin are configured as trusted x86_64-linux Nix remote builders. Client hosts import modules/nix-remote-builders.nix through common.nix, so NixOS hosts in this flake will try to use both builders except for the current host itself.
Builder access uses the nixremote user declared in modules/nix-builder.nix. Client private keys live at /root/.ssh/nix-remote-builder; their public keys are declared in users.users.nixremote.openssh.authorizedKeys.keys.
Add client access#
On the client, generate the key and print its public half:
sudo install -d -m 700 /root/.ssh
sudo ssh-keygen -t ed25519 -N '' -C "nix-remote-builder@$(hostname)" -f /root/.ssh/nix-remote-builder
sudo cat /root/.ssh/nix-remote-builder.pub
Add the public key to modules/nix-builder.nix, then rebuild the builders once:
sudo nixos-rebuild switch --flake .#shizuri
sudo nixos-rebuild switch --flake .#odin
Trust builder host keys on the client:
sudo ssh-keyscan -H shizuri odin | sudo tee -a /root/.ssh/known_hosts >/dev/null
NixOS clients#
NixOS hosts in this flake already import the remote builder config through common.nix. After adding client access, rebuild the client:
sudo nixos-rebuild switch --flake .#<client-hostname>
Smoke test:
sudo ssh -i /root/.ssh/nix-remote-builder nixremote@shizuri nix-store --version
sudo ssh -i /root/.ssh/nix-remote-builder nixremote@odin nix-store --version
sudo nix build nixpkgs#hello --max-jobs 0 -L
Standalone Home Manager clients#
Standalone Home Manager uses the host's Nix daemon. After adding client access, put the builder list in /etc/nix/nix.conf:
experimental-features = nix-command flakes
builders-use-substitutes = true
builders = ssh-ng://nixremote@shizuri x86_64-linux /root/.ssh/nix-remote-builder 24 4 nixos-test,benchmark,big-parallel,kvm - ; ssh-ng://nixremote@odin x86_64-linux /root/.ssh/nix-remote-builder 24 4 nixos-test,benchmark,big-parallel,kvm -
Restart the daemon and run Home Manager:
sudo systemctl restart nix-daemon
home-manager switch --flake .#noah
Linux builders cannot build normal Darwin outputs; homeConfigurations.noah-aleister needs Darwin builders.
Set up a new build host#
Import modules/nix-builder.nix from the new host configuration:
{
imports = [
../../modules/nix-builder.nix
];
}
Add a matching entry to the builders list in modules/nix-remote-builders.nix.
Rebuild the new builder first, then rebuild each client that should use it:
sudo nixos-rebuild switch --flake .#new-builder
sudo ssh-keyscan -H new-builder | sudo tee -a /root/.ssh/known_hosts >/dev/null
sudo nixos-rebuild switch --flake .#<client-hostname>
Maintenance#
Regular maintenance tasks:
- Update flakes:
nix flake update - Garbage collect:
nix-collect-garbage -d(also automatic viacommon.nix) - Check configuration:
nix flake check
License#
This configuration is personal and not licensed for redistribution.