This NixOS configuration uses a modular architecture for better maintainability, reusability, and clarity.
.
├── flake.nix # Main flake entry point
├── modules/ # NixOS system modules
│ ├── default.nix # Module exports
│ ├── profiles/ # High-level system profiles
│ │ ├── common.nix # Base configuration (nix settings, SSH config, etc.)
│ │ ├── client.nix # Desktop/laptop profile
│ │ └── server.nix # Server/headless profile
│ ├── features/ # Feature modules with explicit enable options
│ │ ├── ai/ # AI/ML tooling
│ │ │ └── default.nix
│ │ ├── desktop/ # Desktop environment features
│ │ │ ├── audio.nix
│ │ │ ├── desktop-manager.nix
│ │ │ └── yubikey.nix
│ │ ├── development/ # Development tools
│ │ │ ├── emacs.nix
│ │ │ └── emacs-ui.nix
│ │ ├── networking/ # Network features
│ │ │ └── nebula.nix
│ │ ├── security/ # Security features
│ │ │ ├── hardening.nix
│ │ │ ├── fail2ban.nix
│ │ │ └── sshd.nix
│ │ └── system/ # System-level features
│ │ ├── locale-fonts.nix
│ │ ├── packages.nix
│ │ └── xdg.nix
│ ├── hardware/ # Hardware-specific configurations
│ │ └── nvidia.nix
│ └── users/ # User management
│ ├── brian/
│ │ ├── default.nix # NixOS user config
│ │ ├── bmg-secrets.yaml
│ │ └── hm-profile/ # Home-manager profile
│ │ ├── default.nix
│ │ ├── git.nix
│ │ └── emacs.nix
│ ├── root.nix
│ └── groups.nix
├── hosts/ # Host-specific configurations
│ ├── arcadia/ # Desktop with NVIDIA
│ ├── argus/ # ML desktop with NVIDIA RTX 5080
│ ├── minerva/ # Laptop with SSH
│ ├── nubes/ # Hetzner server
│ └── caelus/ # Hetzner cloud (Nebula lighthouse)
├── home/ # Home-manager configurations
│ ├── profiles/
│ │ ├── client.nix # Desktop user environment
│ │ └── server.nix # Minimal server user environment
│ └── features/ # Home-manager feature modules
│ ├── apps/
│ ├── browsers/
│ ├── development/
│ ├── security/
│ └── shell/
├── packages/ # Custom packages and overlays
│ ├── rebiber/
│ └── scripts/
└── nix/ # Flake infrastructure
├── checks.nix
├── deployments.nix
├── devshell.nix
├── nixpkgs.nix
└── treefmt.nix
All features are declared with clear enable options under the features namespace:
features = {
desktop.audio.enable = true;
development.emacs.enable = true;
networking.nebula.enable = true;
security.sshd.enable = true;
};Profiles are high-level configurations that enable sensible defaults for different system types:
profile-common: Base configuration for all systems (nix settings, SSH config, build machines)profile-client: Desktop/laptop systems (GNOME, audio, development tools, home-manager)profile-server: Headless servers (SSH, fail2ban, minimal packages, home-manager)
Each feature module follows this pattern:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.features.<category>.<feature>;
in
{
options.features.<category>.<feature> = {
enable = lib.mkEnableOption "feature description";
# Additional options...
};
config = lib.mkIf cfg.enable {
# Feature implementation
};
}Host configurations are minimal and declarative:
{
imports = [
self.nixosModules.profile-client
self.nixosModules.hardware-nvidia
];
features.networking.nebula = {
enable = true;
ca = config.sops.secrets.nebula-ca.path;
# ...
};
# Hardware-specific config
hardware.cpu.amd.updateMicrocode = true;
# Network interfaces
networking.hostName = "arcadia";
system.stateVersion = "22.05";
}- Type: Desktop
- Profile: client
- Hardware: AMD CPU, NVIDIA GPU
- Features: GNOME, audio, Emacs, Nebula network
- Type: ML Desktop
- Profile: client
- Hardware: Intel CPU, NVIDIA RTX 5080 GPU
- Features: GNOME, audio, Emacs, Nebula network, AI/ML (Ollama + Goose)
- Type: Laptop (Lenovo ThinkPad X1 9th Gen)
- Profile: client
- Hardware: Intel CPU, encrypted storage
- Features: GNOME, audio, Emacs, Nebula network, SSH server
- Type: Hetzner dedicated server
- Profile: server
- Hardware: AMD CPU, disko-managed disks
- Features: SSH, fail2ban, Nebula network
- Type: Hetzner cloud server (Nebula lighthouse)
- Profile: server
- Hardware: Intel CPU (virtualized), disko-managed disks
- Features: SSH, fail2ban, Nebula network (lighthouse mode)
- Create host directory:
mkdir -p hosts/newhostname - Create
hosts/newhostname/default.nix:
{
self,
lib,
...
}:
{
imports = [
self.nixosModules.profile-client # or profile-server
# Add hardware-specific modules if needed
];
# Enable desired features
features = {
desktop.audio.enable = true;
# ...
};
# Hardware configuration
nixpkgs.hostPlatform = "x86_64-linux";
# ... rest of hardware config
system.stateVersion = "24.11";
}- Add to
hosts/default.nix:
flake.nixosModules = {
# ...
host-newhostname = import ./newhostname;
};
flake.nixosConfigurations = {
# ...
newhostname = lib.nixosSystem {
inherit specialArgs;
modules = [ self.nixosModules.host-newhostname ];
};
};- Create feature module:
modules/features/<category>/<feature>.nix - Define options and configuration:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.features.<category>.<feature>;
in
{
options.features.<category>.<feature> = {
enable = lib.mkEnableOption "feature description";
};
config = lib.mkIf cfg.enable {
# Implementation
};
}- Export in
modules/default.nix:
flake.nixosModules = {
# ...
feature-<name> = import ./features/<category>/<feature>.nix;
};- Import in relevant profile if it should be enabled by default:
imports = [
# ...
self.nixosModules.feature-<name>
];
config = {
features.<category>.<feature>.enable = lib.mkDefault true;
};- Clarity: Easy to see what's enabled on each host
- Reusability: Features can be shared across different system types
- Maintainability: Changes to features are isolated and don't affect other parts
- Testability: Individual features can be tested independently
- Documentation: Structure self-documents the system capabilities
- Flexibility: Easy to override defaults per-host
- Type Safety: Explicit options provide better error messages
nixos/*.nix→modules/features/*/(with options)hosts/common.nix→modules/profiles/common.nixhosts/common-client.nix→modules/profiles/client.nixhosts/common-server.nix→modules/profiles/server.nixusers/*.nix→modules/users/config.setup.device.isClient→ Profile selectionconfig.my-nebula-network→config.features.networking.nebula
All hosts have been verified to build successfully:
nix flake check
nixos-rebuild build --flake .#arcadia
nixos-rebuild build --flake .#minerva
nixos-rebuild build --flake .#nubes
nixos-rebuild build --flake .#caelusTo apply on current system:
rebuild-host # or: sudo nixos-rebuild switch --flake .#$HOSTNAME