Running microVMs in Proxmox VE, The Easy Way - Tao of Mac
Rui Carmo
Tao of Mac
Jun 18th 2026 · 15 min read<br>·<br>#containers<br>#homelab<br>#kvm<br>#microvm<br>#proxmox<br>#qemu<br>#virtualization
Running microVMs in Proxmox VE, The Easy Way
I’ve been running a mixed Proxmox cluster for years – four nodes of wildly different capability, from an Atom x5-Z8350 with 2 GB of RAM (a z83ii, currently offline after years of faithful service as a baseline torture device) up to an i7-12700 with 128 GB (borg, my main homelab server).
This year, somewhere along the way between writing agentbox and all the hype around agentic sandboxes I got tired of the eternal compromise between LXC containers and full virtual machines, and ended up building pve-microvm – a Debian package that adds QEMU’s microvm machine type as a first-class managed guest in Proxmox VE.
This isn’t a quick hack. Well, the first version was, actually, but it’s gone quite a bit farther than that, and certainly farther than I expected.
It now ships a custom kernel, patches the Perl internals to provide Proxmox web UI integration, and, due to my usual fascination with offbeat operating systems, ended up supporting (as of this writing) 21 guest OS types from Debian to NetBSD to Plan9.
Yes, I completely brought it upon myself to run Plan9 in a microVM, and yes, it works.
Finding the Right Balance<br>After a few rounds of cluster cleanups and migrations, it’s now my daily driver for running Gitea, Caddy reverse proxies, mini-firewalls, and the AI agent that’s helping me clean up this post.
Proxmox gives you two main options out of the box:
LXC containers start instantly, share the host kernel, and are spectacularly efficient. But they’re not isolated – a kernel exploit in one container compromises everything. You can’t run a different OS. You can’t easily nest Docker inside them without ending up (eventually) wrestling with fuse-overlayfs gymnastics. And certain workloads (anything needing custom kernel modules, or CAP_SYS_ADMIN in anger) simply don’t fit.
Full VMs give you hardware isolation via KVM/VT-x, but they boot SeaBIOS or OVMF, sedately walk through GRUB as they yawn their way out of bed, probe a forest of emulated legacy devices (IDE controllers, VGA, USB hubs, PCI bridges), and typically take 5-10 seconds to reach a login prompt. Each one carries the overhead of that entire emulated chipset sitting in memory.
What I wanted was the security boundary of a VM with the startup characteristics of a container. QEMU’s microvm machine type – originally developed for Firecracker-style workloads – strips all of that away. No BIOS, no GRUB, no legacy devices. Direct kernel boot into a minimal virtio-only environment. The result: sub-300ms boot to a fully networked guest with a QEMU agent, running inside its own KVM hardware isolation boundary.
Comparison of Standard VM, microVM, and LXC Container isolation and boot characteristics
Now, let me be clear: I’m not spawning hundreds of these things. I have Azure for that – but I do want to run Gitea Actions workers, have a very limited set of hardware resources, and got fed up with the time it took for one particular VM to boot repeatedly…
What It Actually Does<br>pve-microvm is a single .deb that patches Proxmox’s qemu-server Perl modules at install time. When you set machine: microvm on a VM config, the standard config_to_command function delegates to my MicroVM.pm, which builds an (almost) completely different QEMU command line:
qemu-system-x86_64 -M microvm,x-option-roms=off,pit=off,pic=off,\<br>isa-serial=on,rtc=on,acpi=on,pcie=on \<br>-kernel /usr/share/pve-microvm/vmlinuz \<br>-initrd /usr/share/pve-microvm/initrd \<br>-append "console=ttyS0 root=/dev/vda rw quiet" \<br>-device virtio-blk-pci-non-transitional,drive=drive-scsi0 \<br>-device virtio-net-pci-non-transitional,netdev=net0 \<br>...
No chipset emulation. No PCI bridges. No VGA. The guest gets a single serial console (which PVE’s xterm.js connects to natively), virtio block devices, and a virtio network interface. Everything rides PCIe transport with non-transitional (modern-only) virtio devices rather than the MMIO transport microvm was originally designed around – for reasons I’ll come to in a moment.
How pve-microvm integrates with Proxmox VE internals
The package ships:
A tiny (12MB) pre-built Linux 6.12.22 kernel compiled from x86_64_defconfig with a minimal overlay – virtio, vsock, virtiofs, 9p, and the modules Docker needs (overlay, veth, bridge, netfilter, BPF), because, well, I’m pragmatic.
A 1 MB initrd that probes virtio devices, finds the root filesystem by label or device path, and does a switch_root in ~150ms
pve-microvm-template – builds root filesystems from any of 12 supported OCI base images, with optional SSH, Docker, and guest agent
pve-oci-import – pulls an OCI image directly into a PVE-managed disk
Web UI extensions – a "Create µVM" button, machine type dropdown, conditional panel hiding for irrelevant settings, and an amber bolt...