Configuration for my NixOS based systems and Home Manager
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Nix 50.2%
Lua 13.1%
Vim Script 4.5%
Shell 4.1%
Other 28.2%
305 10 9

Clone this repository

https://tangled.org/ngp.computer/nixos https://tangled.org/did:plc:hjp23blu4y7bgf7zrzhzdemi/nixos
git@tangled.org:ngp.computer/nixos git@tangled.org:did:plc:hjp23blu4y7bgf7zrzhzdemi/nixos

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

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 modules
  • hardware-configuration.nix - Auto-generated hardware config
  • boot.nix - Bootloader and kernel settings
  • networking.nix - Network configuration
  • packages.nix - System packages
  • services.nix - Service definitions
  • gui.nix - GUI/Desktop environment settings (where applicable)
  • users.nix - Host-specific users and groups

Adding a New Host#

  1. Create a new directory under host-specific/<hostname>/
  2. Copy the hardware configuration from the target machine:
    nixos-generate-config --show-hardware-config > host-specific/<hostname>/hardware-configuration.nix
    
  3. Create configuration.nix importing necessary modules
  4. Add the host to flake.nix in the nixosConfigurations output:
    nixosConfigurations.newhost = basicSystem {
      useUnstable = true;
      modules = [
        ./host-specific/newhost/configuration.nix
      ];
    };
    
  5. 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 .age extension
  • 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:

  1. Add the secret file to secrets/
  2. Define recipients in secrets/secrets.nix
  3. Encrypt: agenix -e secrets/my-secret.age
  4. 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 formatting
  • nil - Nix language server / linter
  • luacheck - Lua linting (for Neovim config)

Key Features#

Overlays#

  • neovim.nix - Pins Neovim to specific version
  • lmstudio.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 via common.nix)
  • Check configuration: nix flake check

License#

This configuration is personal and not licensed for redistribution.