Phase 1: a golden image, and why SeaBIOS won this round
Building the cloud-init template every VM clones from. And learning the hard way that UEFI + cloud images + a serial console hides your boot failures.
Phase 1 is the toolchain and the golden image: one cloud-init template that every future VM clones from. Get it right once, stamp it out forever. I got it wrong twice first.
Cloud image, not the installer ISO
The template is built from the distro’s cloud image, a pre-installed disk with cloud-init baked in, not the live-server ISO. The ISO is an installer; you’d have to script an unattended install and reboot for every clone. The cloud image you just clone, and cloud-init paints on the hostname, user, SSH key and static IP at first boot. It’s the whole reason a clone is ready in seconds.
The firmware trap
I built the template with UEFI (OVMF) and a serial-only console, thinking ahead to GPU passthrough. The first clone booted to a black screen at “starting serial terminal” and never got an IP. The trap: under UEFI, early boot writes to the emulated VGA, which I’d disabled. So the screen stays blank while the real failure happens invisibly. It’s printf debugging with the printf switched off. SeaBIOS boots these cloud images with zero drama. I switched the base template to SeaBIOS, kept a visible console, and parked UEFI for the one host that genuinely needs it.
# Golden template, the fix: SeaBIOS + a visible VGA console (not serial-only).
qm set <template-id> --bios seabios --vga std --serial0 socket
# OVMF (UEFI) + serial-only booted to a black screen: early boot wrote to the
# emulated VGA I'd disabled, so the failure happened off-screen.
If you can’t see the console, you’re not debugging a boot. You’re guessing at one.
The other two gotchas
A tiny VM with too little RAM doesn’t boot slowly. It kernel-panics on memory mid-cloud-init. And pinning a “latest” cloud image by URL bites you the day upstream rebuilds it: pin a dated snapshot and verify its checksum, or your cache and the published hash quietly disagree.
Next: Phase 2, internal DNS, and a proper chicken-and-egg.