This repository has been archived on 2026-07-30. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
nixos/docs/proxmox-images.md
T
beatzaplentyandClaude Sonnet 5 feee2f1679 Add Proxmox VM disk-image building; fix disko confirmation bypass
modules/disko/proxmox.nix gains imageSize (20G default) and a
per-host imageName (networking.hostName, so every proxmox-* host
produces a distinctly named image instead of an identical main.raw).
This is the same disko.devices config already used to format a real
disk on install, so it's available for every proxmox-* target with no
per-host changes needed:

  nix build .#nixosConfigurations.<host>.config.system.build.diskoImagesScript
  sudo ./result --build-memory 2048

docs/proxmox-images.md covers building, host-key pre-seeding via
disko's --pre-format-files (same host-keys/ workflow as the installer
and LXC tarball paths), and the qm import/attach sequence for
deploying the result to Proxmox.

Also fixes a real bug in auto-install.sh found while testing: the
disko confirmation bypass used --yes, which disko's CLI doesn't
recognize at all (the actual flag is --yes-wipe-all-disks) — so the
"skip confirmation" flag was silently a no-op and the interactive
prompt kept appearing regardless.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01La55Nsss8jZ7ZuzUV9mfot
2026-07-20 07:01:33 +10:00

3.9 KiB

Proxmox VM disk images

proxmox-* hosts (VM platform, not lxc-*) can be built as standalone, ready-to-attach .raw disk images via disko's own image-builder — no nixos-install, no live installer boot. This uses the same disko.devices config (modules/disko/proxmox.nix) already used to format a real disk on install, so there's nothing host-specific to write; it's available for every proxmox-* target automatically.

Building

nix build .#nixosConfigurations.proxmox-server.config.system.build.diskoImagesScript
sudo ./result --build-memory 2048

This produces <hostname>.raw in the current directory (e.g. server.raw for proxmox-server, matching networking.hostName, not the flake attribute name — every proxmox-* host gets a distinctly named image instead of all of them producing an identical main.raw). The script builds inside a temporary QEMU VM and moves the finished image out to the working directory when done; --build-memory controls how much RAM that build VM gets.

disko.devices.disk.main.imageSize (currently 20G, in modules/disko/proxmox.nix) sets the image's total size — disko doesn't support auto-resizing, so this needs to comfortably fit ESP + swap + root at build time. Grow the virtual disk (and resize the filesystem) in Proxmox after attaching if a host needs more than that; this is the normal way to size these images, not a one-time decision to get exactly right up front.

Host keys

The disko image script runs a real activation pass inside its temporary build VM while constructing the image — the same sops-nix activation-before-first-boot problem the installer and LXC tarball workflows have (see docs/auto-installer.md) applies here too, unmodified. Disko has a native mechanism for it:

sudo ./result \
  --pre-format-files host-keys/server_ssh_host_ed25519_key /etc/ssh/ssh_host_ed25519_key \
  --pre-format-files host-keys/server_ssh_host_ed25519_key.pub /etc/ssh/ssh_host_ed25519_key.pub \
  --build-memory 2048

Generate the key first with scripts/prepare-host-key.sh <hostname>, same as any other host — see docs/auto-installer.md for the full sops.yaml registration walkthrough.

Deploying to Proxmox

The image needs UEFI (OVMF), not Proxmox's default SeaBIOS — modules/boot/efi.nix uses systemd-boot, which only works with UEFI firmware. virtio-scsi is safe to use as the disk bus: hardware-configuration/vm/proxmox.nix already includes virtio_scsi in its initrd kernel modules.

  1. Copy the image to the Proxmox host:

    scp server.raw root@<proxmox-host>:/var/lib/vz/import/
    
  2. Create an empty VM shell (no disk yet) — replace <vmid> with a free ID and <storage> with your storage pool's name (pvesm status or Datacenter → Storage in the web UI):

    qm create <vmid> --name proxmox-server --memory 2048 --cores 2 \
      --net0 virtio,bridge=vmbr0 \
      --bios ovmf --machine q35 \
      --scsihw virtio-scsi-pci \
      --efidisk0 <storage>:1,efitype=4m,pre-enrolled-keys=0
    

    (--efidisk0 is required for UEFI — it's where OVMF persists boot-entry NVRAM; without it, systemd-boot's boot entry may not survive a reboot.)

  3. Import the raw disk into storage:

    qm importdisk <vmid> /var/lib/vz/import/server.raw <storage>
    

    This prints the resulting disk identifier (e.g. vm-<vmid>-disk-1).

  4. Attach it and set it as the boot disk:

    qm set <vmid> --scsi0 <storage>:vm-<vmid>-disk-1
    qm set <vmid> --boot order=scsi0
    
  5. Boot it:

    qm start <vmid>
    

No install step — it boots straight into the already-activated system.

Why not nix build .#nixosConfigurations.<host>.config.system.build.vm?

That's a different, unrelated feature — system.build.vm (nixos-rebuild build-vm) produces an ephemeral QEMU script for locally testing a configuration, not a distributable disk image. It's not part of this workflow.