Files
2026-02-05 18:47:42 +00:00

6.5 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
Host Configuration Organization HIGH Prevents configuration chaos across multiple hosts hosts,modules,base-config,directory-structure

Why This Matters

Proper host configuration organization prevents duplication, makes maintenance easier, and ensures consistency across multiple machines.

Directory Structure

nixos-config/
├── flake.nix                    # Top-level flake
├── hosts/
│   ├── laptop/
│   │   ├── default.nix          # Host-specific config
│   │   ├── hardware-configuration.nix  # Generated (don't edit)
│   │   └── home.nix             # Home Manager config
│   ├── desktop/
│   │   ├── default.nix
│   │   ├── hardware-configuration.nix
│   │   └── home.nix
│   └── base.nix                 # Shared by all hosts (optional)
├── modules/                     # Reusable NixOS modules
├── overlays/                    # Custom overlays
├── home-manager/                # Shared Home Manager configs
│   ├── shell/
│   ├── applications/
│   └── common.nix
└── secrets/                     # Age-encrypted secrets

Host Configuration Pattern

Incorrect: Everything in one file

# hosts/laptop/default.nix
{ config, pkgs, ... }:
{
  # Hardware config (copied from hardware-configuration.nix)
  boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" ];
  # ... 50 lines of hardware config ...

  # Network config
  networking.hostName = "laptop";
  networking.networkmanager.enable = true;

  # User config
  users.users.john = {
    isNormalUser = true;
    extraGroups = [ "wheel" "networkmanager" ];
  };

  # Packages
  environment.systemPackages = with pkgs; [ vim git wget ];

  # Services
  services.openssh.enable = true;

  # Home Manager
  imports = [
    ./home.nix  # Or inline the entire home config
  ];
}

Problems:

  • Hardware config duplicated (should import hardware-configuration.nix)
  • User config duplicated across hosts
  • No shared configuration
  • Hard to maintain

Correct: Modular structure

# hosts/laptop/default.nix
{ inputs, pkgs, pkgs-stable, system, ... }:
{
  imports = [
    ./hardware-configuration.nix  # Import hardware config
    ../base.nix                  # Import shared config
    inputs.home-manager.nixosModules.home-manager
    {
      home-manager.useGlobalPkgs = true;
      home-manager.useUserPackages = true;
      home-manager.users.john = import ./home.nix;
      home-manager.extraSpecialArgs = {
        inherit inputs pkgs-stable system;
      };
      nixpkgs.overlays = [ inputs.some-overlay.overlays.default ];
    }
  ];

  # Host-specific config only
  networking.hostName = "laptop";
}

Shared Base Configuration

# hosts/base.nix
{ config, pkgs, inputs, ... }:
{
  # Network
  networking.networkmanager.enable = true;

  # Time and locale
  time.timeZone = "America/New_York";
  i18n.defaultLocale = "en_US.UTF-8";

  # Users (shared across all hosts)
  users.users.john = {
    isNormalUser = true;
    extraGroups = [ "wheel" "networkmanager" ];
  };

  # Common packages
  environment.systemPackages = with pkgs; [
    vim
    git
    wget
    tmux
  ];

  # Common services
  services.openssh.enable = true;

  # Nix settings
  nix.settings.experimental-features = [ "nix-command" "flakes" ];
}

Hardware Configuration

# hosts/laptop/default.nix
{ ... }:
{
  imports = [
    ./hardware-configuration.nix  # Generated by nixos-generate-config
    ../base.nix
    # ...
  ];

  networking.hostName = "laptop";
}

Important: Don't edit hardware-configuration.nix manually. It's generated by nixos-generate-config and should be replaced when hardware changes.

Home Manager Configuration

Host-specific home.nix

# hosts/laptop/home.nix
{ config, pkgs, inputs, ... }:
{
  imports = [
    ../../home-manager/shell
    ../../home-manager/applications
    ../../home-manager/common.nix
  ];

  # Host-specific user config
  home.packages = with pkgs; [
    laptop-specific-package
  ];
}

Shared Home Manager configs

# home-manager/shell/default.nix
{ config, pkgs, ... }:
{
  imports = [
    ./fish
    ./neovim
    ./git
  ];
}

# home-manager/common.nix
{ config, pkgs, ... }:
{
  home.packages = with pkgs; [
    jq
    ripgrep
    fzf
  ];

  programs.git.enable = true;
  programs.git.userName = "John Doe";
  programs.git.userEmail = "john@example.com";
}

Multiple Hosts Example

# flake.nix
outputs = { self, nixpkgs, home-manager, ... }@inputs: {
  nixosConfigurations.laptop = nixpkgs.lib.nixosSystem {
    specialArgs = { inherit inputs; };
    modules = [ ./hosts/laptop ];
  };

  nixosConfigurations.desktop = nixpkgs.lib.nixosSystem {
    specialArgs = { inherit inputs; };
    modules = [ ./hosts/desktop ];
  };

  nixosConfigurations.server = nixpkgs.lib.nixosSystem {
    specialArgs = { inherit inputs; };
    modules = [ ./hosts/server ];
  };
};

Each host uses the same base.nix but can override settings:

# hosts/server/default.nix
{ ... }:
{
  imports = [ ../base.nix ./hardware-configuration.nix ];

  # Override time zone for server
  time.timeZone = "UTC";

  # Add server-specific packages
  environment.systemPackages = with pkgs; [
    htop
    iotop
  ];
}

Module Pattern

For reusable functionality, create modules:

# modules/docker.nix
{ config, pkgs, ... }:
{
  virtualisation.docker = {
    enable = true;
    enableOnBoot = true;
  };

  users.users.john.extraGroups = [ "docker" ];
}

Use in host config:

# hosts/laptop/default.nix
{ ... }:
{
  imports = [
    ../base.nix
    ../../modules/docker  # Import module
    ./hardware-configuration.nix
  ];
}

Common Mistakes

  1. Editing hardware-configuration.nix: Changes are lost when regenerating. Put host-specific config in default.nix instead.

  2. Duplicating config across hosts: Use base.nix or modules for shared configuration.

  3. Not separating host-specific and user-specific: Keep host config in hosts/*/default.nix, user config in home.nix or home-manager/.

  4. Mixing concerns: Don't put shell config in system packages. Use Home Manager for user-level packages.

Quick Checklist

  • Each host imports hardware-configuration.nix
  • Shared config in base.nix or modules
  • Home Manager configured in host file
  • Host-specific settings only in host's default.nix
  • User config in home.nix or home-manager/
  • No duplication of hardware config
  • No duplication of user config