All the tings needed to build a minimal NixOS ISO which installs itself. Used in my HomeLab to spin up new hosts.
  • Shell 84.2%
  • Nix 15.8%
Find a file
2026-06-23 16:13:00 +02:00
.forgejo/workflows Update .forgejo/workflows/build.yml 2026-04-05 22:05:29 +00:00
ssh feat(security): update SSH keys, password hash, and add warning about default credentials 2026-03-19 16:07:01 +01:00
tests feat(install): add support for automated and manual installation modes with enhanced networking and disk configuration options 2026-06-23 16:13:00 +02:00
.gitignore feat(iso): add automated NixOS ISO build and installation scripts 2026-03-19 12:13:05 +01:00
bootloader.nix feat(install): add support for automated and manual installation modes with enhanced networking and disk configuration options 2026-06-23 16:13:00 +02:00
disko-config.nix feat(install): add support for automated and manual installation modes with enhanced networking and disk configuration options 2026-06-23 16:13:00 +02:00
flake.lock Add prompts for disk and network setup. This results in a regression regarding automated installation since there needs to be user input for it to install. 2026-06-22 17:12:45 +02:00
flake.nix Add prompts for disk and network setup. This results in a regression regarding automated installation since there needs to be user input for it to install. 2026-06-22 17:12:45 +02:00
install.sh feat(install): add support for automated and manual installation modes with enhanced networking and disk configuration options 2026-06-23 16:13:00 +02:00
installer-defaults.conf feat(install): add support for automated and manual installation modes with enhanced networking and disk configuration options 2026-06-23 16:13:00 +02:00
iso-configuration.nix feat(install): add support for automated and manual installation modes with enhanced networking and disk configuration options 2026-06-23 16:13:00 +02:00
LICENSE feat(security): update SSH keys, password hash, and add warning about default credentials 2026-03-19 16:07:01 +01:00
networking.nix Add prompts for disk and network setup. This results in a regression regarding automated installation since there needs to be user input for it to install. 2026-06-22 17:12:45 +02:00
README.md feat(install): add support for automated and manual installation modes with enhanced networking and disk configuration options 2026-06-23 16:13:00 +02:00
system-configuration.nix feat(install): add support for automated and manual installation modes with enhanced networking and disk configuration options 2026-06-23 16:13:00 +02:00

NixOS ISO Builder

Minimal, single-purpose NixOS ISO that boots, formats disks with Disko, installs NixOS, and reboots.

Build

nix build .#nixosConfigurations.iso.config.system.build.isoImage

Output ISO: result/iso/*.iso

Local Checks

Run helper tests without starting the installer:

bash tests/install-helpers-test.sh

The test sets INSTALL_SH_TEST=1, sources install.sh, and validates helper logic for IP validation, disk selection, generated networking, and GRUB mirrored boot config. It does not format disks or run installation.

Install Behavior

The installer uses NixOS 26.05, nix-community/disko, and a btrfs root filesystem.

At startup, the installer asks whether to use the default unattended profile from installer-defaults.conf. Any keyboard input, including Enter alone, selects manual install. Waiting 30 seconds without keyboard input accepts defaults and proceeds without the final WIPE prompt.

Default profile:

  • Network: DHCP
  • NIC: first connected non-loopback interface, falling back to first detected NIC
  • Disk layout: single disk if only one disk exists; otherwise RAID1 using the two smallest detected disks
  • Confirmation: disabled for unattended defaults

Manual installs prompt for networking:

  1. DHCP
  2. Manual static IP

If multiple NICs are present, the installer asks which single NIC to configure and lists each interface with name, MAC address, link state, speed when available, and driver when available. Other NICs are left unconfigured for post-install setup.

For static IP installs, enter an address, prefix length, default gateway, and DNS servers. Each DNS server is tested against https://cache.nixos.org/nix-cache-info before disks are wiped. The same network choice is written to the installed system as /etc/nixos/networking.nix, bound to the selected NIC MAC address and renamed to install0.

Single-disk systems install automatically:

  • GPT partition table
  • 2G EFI System Partition mounted at /boot
  • Remaining space as btrfs mounted at /
  • btrfs mount options: compress=zstd, noatime

Manual installs print a final summary before formatting. Type WIPE to continue or RESTART to return to network/disk selection. If validation fails, the installer restarts its choices and keeps previous inputs as defaults where possible.

Manual multi-disk installs prompt on the console:

  1. Single disk install
  2. RAID1 install
  3. RAID0 install

For RAID0 and RAID1, the installer asks which disks to include. Enter two or more disk numbers separated by spaces, for example 1 3 4. The selected order controls the ESP mountpoints: first disk gets /boot, second /boot2, and so on.

RAID modes use native btrfs multi-device profiles:

disks -> GPT partitions -> native btrfs RAID0/RAID1 /

RAID1 uses btrfs raid1 for data and metadata, so btrfs scrub can detect a bad copy and repair it from the healthy mirror. RAID0 uses btrfs raid0 for data and metadata; one failed disk loses the filesystem.

Every selected disk gets a 2G ESP. The installed system uses GRUB mirroredBoots so bootloader files are written to /boot, /boot2, and further ESP mountpoints as needed.

Default Credentials

WARNING: This repository contains a pre-generated SSH private key and a default password. These are intended as a quick-start convenience only. You MUST replace them before building the ISO, or at the very least immediately after installation. Using the defaults in a non-isolated environment is a serious security risk.

Value
User luna
Password Admin12345
SSH private key ssh/id_ed25519 (committed to this repo)

To use the provided key:

ssh -i ssh/id_ed25519 luna@<ip>

Customisation

Edit system-configuration.nix before building the ISO.

Edit installer-defaults.conf to change the unattended install profile and timeout.

Edit networking.nix to change the default target networking config. The installer overwrites it during installation with the selected DHCP or static configuration.

Edit disko-config.nix to change the disk layout. The default layout is btrfs-only and does not include ext4, ZFS, or mdadm options.

SSH Key

Replace the openssh.authorizedKeys.keys value with your own public key:

openssh.authorizedKeys.keys = [
  "ssh-ed25519 AAAA... your-key-here"
];

Password

Generate a hashed password with:

mkpasswd -m sha-512

Paste the resulting hash into system-configuration.nix:

hashedPassword = "$6$...";

If mkpasswd is not available, install it with apt install whois (Debian/Ubuntu) or nix-shell -p mkpasswd.

Static IP

Replace networking.useDHCP = true with:

networking.useDHCP = false;
networking.interfaces.eth0.ipv4.addresses = [{
  address = "192.168.1.100";
  prefixLength = 24;
}];
networking.defaultGateway = "192.168.1.1";
networking.nameservers = [ "1.1.1.1" "8.8.8.8" ];

Adjust interface name (eth0), address, gateway, and nameservers as needed.

Deploy (Proxmox)

  1. Upload the ISO to Proxmox ISO storage
  2. Create a VM with:
    • BIOS: OVMF (UEFI)
    • Add an EFI disk — uncheck Pre-Enroll keys (otherwise Secure Boot will reject the ISO)
    • Attach the ISO as a CD/DVD drive (boot order: CD first)
  3. Start the VM — installation runs automatically
  4. VM reboots into the installed system; remove/detach the ISO

To monitor the installation progress from the console:

systemctl status auto-install
journalctl -u auto-install -f

SSH Access

User: luna Key: the ed25519 key in system-configuration.nix

ssh luna@<ip>

Password auth is disabled. luna is in the wheel group (sudo access).