Files

6.1 KiB

name, description, argument-hint
name description argument-hint
nix-new-host Scaffold a new NixOS host in this flake: create host directory, config files, wire into flake.nix, and set up Home Manager users. Use when adding a new machine (desktop, laptop, or server) to the Nix-Vibe configuration. <hostname> [desktop|server]

New Host Scaffolding

When to Use

  • Adding a brand new machine to the Nix-Vibe configuration
  • User asks to "add a host", "create a new machine config", or "scaffold a server/laptop"
  • Migrating a new device into this flake-based setup

Procedure

1. Gather Information

Before creating files, confirm with the user:

  • Hostname (e.g., new-laptop)
  • Type: Desktop/laptop (needs GUI) or Server (headless, CLI only)
  • Users who will have Home Manager configs on this host
  • Any special hardware (NVIDIA GPU, fingerprint sensor, etc.)
  • Any services this host should run

2. Create Host Directory

mkdir -p hosts/<hostname>

3. Create Required Host Files

hosts/<hostname>/hardware-configuration.nix

Generate on the target machine after NixOS install:

nixos-generate-config --show-hardware-config > hosts/<hostname>/hardware-configuration.nix

If the target machine isn't available yet, create a minimal placeholder:

# hardware-configuration.nix for <hostname>
# Generated placeholder — run nixos-generate-config on the target machine
{
  config,
  lib,
  pkgs,
  ...
}:
{
  imports = [ ];
  boot.initrd.availableKernelModules = [ ];
  boot.initrd.kernelModules = [ ];
  boot.kernelModules = [ ];
  fileSystems."/" = {
    device = "/dev/disk/by-label/nixos";
    fsType = "ext4";
  };
  swapDevices = [ ];
  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
  hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

hosts/<hostname>/disko-config.nix

Copy from an existing host of the same type (desktop vs server) and adjust disk layout:

cp hosts/x1carbon/disko-config.nix hosts/<hostname>/disko-config.nix
# Then edit to match the target disk layout

hosts/<hostname>/configuration.nix

Use the appropriate template below.

Desktop/laptop template:

{
  config,
  pkgs,
  inputs,
  lib,
  ...
}:
{
  imports = [
    ./hardware-configuration.nix
    ../../modules/core/common.nix
    ../../modules/desktop/gui.nix
    (import ../../modules/storage/disko.nix {
      inherit inputs lib config;
      diskoConfigPath = ./disko-config.nix;
    })
    ../../modules/desktop/gnome.nix
    ../../modules/core/management.nix
    ../../modules/core/podman.nix
    ../../modules/core/dev.nix
  ];

  networking.hostName = "<hostname>";

  hardware.graphics.enable = true;
  hardware.graphics.enable32Bit = true;
}

Server template:

{
  config,
  pkgs,
  lib,
  inputs,
  ...
}:
{
  imports = [
    ../../modules/core/common.nix
    (import ../../modules/storage/disko.nix {
      inherit inputs lib config;
      diskoConfigPath = ./disko-config.nix;
    })
    ./hardware-configuration.nix
    ../../modules/core/podman.nix
  ];

  networking.hostName = "<hostname>";
}

4. Wire into flake.nix

Add users in hostUsers:

hostUsers = {
  # ...existing hosts...
  <hostname> = [ "user1" "user2" ];
};

Add nixosConfiguration:

If desktop/laptop (uses full overlays):

nixosConfigurations = {
  # ...existing configs...
  <hostname> = mkNixosSystem "<hostname>" { };
};

If server (uses serverOverlays):

nixosConfigurations = {
  # ...existing configs...
  <hostname> = mkNixosSystem "<hostname>" {
    hostOverlays = serverOverlays;
  };
};

5. Create Home Manager User Configs (if needed)

If the host has users without existing Home Manager configs, create:

mkdir -p home-manager/users

Minimal user template (home-manager/users/<username>.nix):

{
  config,
  pkgs,
  lib,
  inputs,
  ...
}:
{
  home-manager.users.<username> = {
    home.username = "<username>";
    home.homeDirectory = "/home/<username>";
    home.stateVersion = "24.11";

    programs.home-manager.enable = true;
    programs.git.enable = true;
  };
}

6. Update README.md

Add the new host to:

  • The Host Roles section with role description and key features
  • The Software Inventory table (add a column for the new host)

7. Register Host in nix-flake-rebuild Skill

The dry-build loop in nix-flake-rebuild is dynamic (hosts are read from nixosConfigurations), so nothing breaks if you skip this — but add <hostname> to its Host Reference table (with the correct Type and Overlay — serverOverlays for servers, Full for desktops/laptops) to keep the overlay reference accurate.

8. Validate

Follow the nix-flake-rebuild skill to validate all changes.

Common Patterns

Adding Desktop Apps

Import app modules in the host config:

imports = [
  # ...existing imports...
  ../../modules/desktop/apps/soundux.nix
  ../../modules/desktop/apps/opencode.nix
];

Adding Services

Import service modules and enable:

imports = [
  # ...existing imports...
  ../../modules/services/immich.nix
];
services.immich-server.enable = true;

Hardware-Specific Modules

imports = [
  # ...existing imports...
  ../../modules/hardware/fingerprint.nix  # if fingerprint reader
  ../../modules/hardware/nvidia.nix       # if NVIDIA GPU
];

For an NVIDIA GPU, enable via the shared option (instead of hand-writing hardware.nvidia):

my.hardware.nvidia = {
  enable = true;
  nvidiaSettings = true;
  package = config.boot.kernelPackages.nvidiaPackages.legacy_580; # optional
};

Shared Users (petere)

The admin user petere is defined once in modules/core/users.nix (imported via common.nix). New hosts do not re-declare the full users.users.petere block — override only what differs:

my.users.petere = {
  hashedPasswordFile = config.sops.secrets."users/petere-password".path;
  subUidStart = 165536;  # optional rootless-podman range
  subGidStart = 165536;
};

petere also needs a Home Manager config in hostUsers (step 4).