297 lines
6.5 KiB
Markdown
297 lines
6.5 KiB
Markdown
---
|
|
title: Host Configuration Organization
|
|
impact: HIGH
|
|
impactDescription: Prevents configuration chaos across multiple hosts
|
|
tags: 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
|
|
|
|
```nix
|
|
# 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
|
|
|
|
```nix
|
|
# 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
|
|
|
|
```nix
|
|
# 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
|
|
|
|
```nix
|
|
# 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
|
|
|
|
```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
|
|
|
|
```nix
|
|
# 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
|
|
|
|
```nix
|
|
# 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:
|
|
|
|
```nix
|
|
# 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:
|
|
|
|
```nix
|
|
# modules/docker.nix
|
|
{ config, pkgs, ... }:
|
|
{
|
|
virtualisation.docker = {
|
|
enable = true;
|
|
enableOnBoot = true;
|
|
};
|
|
|
|
users.users.john.extraGroups = [ "docker" ];
|
|
}
|
|
```
|
|
|
|
Use in host config:
|
|
|
|
```nix
|
|
# 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
|