Skip to content

Latest commit

 

History

History
176 lines (145 loc) · 5.9 KB

File metadata and controls

176 lines (145 loc) · 5.9 KB
title Host files: disko, hardware-config, default.nix
time 15 minutes

Host files: disko, hardware-config, default.nix

Prerequisite: Anatomy of an instance repo.

Outcome: you know what each file under hosts/<name>/ is for, when to change it, and how to escape the defaults when your target is not a plain Hetzner Cloud VM.

Every host has its own directory, hosts/<name>/, imported from the inventory (modules = [ ./hosts/<name> ]). add-host scaffolds it with three files.

The three files

hosts/web-1/
|-- default.nix
|-- disko.nix
`-- hardware-configuration.nix
  • default.nix -- the entry point. Imports the two others and is where your per-host NixOS options go (services, users, opened ports). You edit this file by hand as the host grows.
  • disko.nix -- the disk layout. Consumed by disko to partition and format the target on install. Written by the preset you pick during add-host, or by you if you pick custom.
  • hardware-configuration.nix -- kernel modules and hardware quirks NixOS needs to boot on the specific machine. Generated by install-host via nixos-anywhere --generate-hardware-config nixos-generate-config. The placeholder add-host leaves is overwritten on first install. You do not hand-edit this file.

Picking a disk layout during add-host

add-host prompts:

Disk layout:
  hetzner-vm
> custom (write disko.nix by hand)

Options are enumerated from templates/disko/*.nix in the nixops repo, plus the always-present custom escape hatch.

  • Preset (e.g. hetzner-vm) -- the file at templates/disko/hetzner-vm.nix is copied verbatim to hosts/<name>/disko.nix. Ready to install-host.
  • custom -- no disko.nix is written. You must create it before install-host, or install-host refuses to run.

The current preset list is intentionally small. When the presets do not fit (bare metal, ZFS, mirror, encryption, non-standard disk names) pick custom and see Escape hatches below.

What install-host does with these files

  1. Checks hosts/<name>/disko.nix exists. Bails if not.
  2. Calls nixos-anywhere --flake .#<name> --generate-hardware-config nixos-generate-config hosts/<name>/hardware-configuration.nix.
  3. nixos-anywhere runs nixos-generate-config on the target inside the installer, writes the result back to your flake, then builds and deploys the fully-formed configuration.
  4. First install: the placeholder hardware-configuration.nix is replaced with the real one. Commit the change.
  5. --force reinstall: the file is regenerated from live hardware -- useful when you swap disks or move the host.

Escape hatches

Writing your own disko.nix

Pick custom in add-host, then drop a file. The disko module is already imported by every host (through nixops.nixosModules.default), so you only set the disko.devices option.

Minimal example for a single-disk VPS with BIOS boot:

# hosts/web-1/disko.nix
{
  disko.devices.disk.main = {
    device = "/dev/sda";
    type = "disk";
    content = {
      type = "gpt";
      partitions = {
        boot = { size = "1M"; type = "EF02"; };  # BIOS boot
        root = {
          size = "100%";
          content = {
            type = "filesystem";
            format = "ext4";
            mountpoint = "/";
          };
        };
      };
    };
  };

  boot.loader.grub = {
    enable = true;
    efiSupport = false;
    device = "/dev/sda";
  };
}

ZFS mirror on two NVMe drives:

# hosts/db-1/disko.nix
{
  disko.devices = {
    disk = {
      x = { device = "/dev/nvme0n1"; type = "disk"; content = { type = "gpt"; partitions = {
        ESP = { size = "1G"; type = "EF00"; content = { type = "filesystem"; format = "vfat"; mountpoint = "/boot"; }; };
        zfs = { size = "100%"; content = { type = "zfs"; pool = "tank"; }; };
      }; }; };
      y = { device = "/dev/nvme1n1"; type = "disk"; content = { type = "gpt"; partitions = {
        zfs = { size = "100%"; content = { type = "zfs"; pool = "tank"; }; };
      }; }; };
    };
    zpool.tank = {
      type = "zpool";
      mode = "mirror";
      rootFsOptions = { compression = "zstd"; atime = "off"; xattr = "sa"; };
      mountpoint = "/";
    };
  };

  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;
  boot.supportedFilesystems = [ "zfs" ];
  networking.hostId = "12345678";  # required by ZFS
}

More layouts (raidz, LUKS, LVM, bcachefs, btrfs subvolumes): nix-community/disko/tree/master/example.

Not sure where to start? Ask Claude to draft one from your target's lsblk output and iterate.

Overriding a preset after add-host

Presets are just files. If you picked hetzner-vm and later need to change the ESP size or filesystem, edit hosts/<name>/disko.nix directly. It is your file now.

If you already ran install-host, disk changes require a wipe -- re-run with install-host <name> --force. Ordinary deploy will not reformat disks.

Contributing a preset back

Common enough to be reusable? Drop a file into templates/disko/ in the nixops repo. add-host picks it up automatically. No code changes needed to enumerate it.

References