MicroVMs
Container workloads with a real kernel boundary: how microVMs differ from VMs, why HosterOS removed the setup they used to need, and how to run a compose stack inside one.
A microVM is a virtual machine with its own kernel that boots in a fraction of the time
a full QEMU guest takes, run on
Cloud Hypervisor instead of QEMU. You put a
compose.yaml in it and it runs your containers — with a hypervisor boundary underneath
instead of a shared kernel.
That is the whole point. Containers share a kernel, which is fine until it is not, and “not” usually means a tenant boundary, an untrusted image, or a compliance question you would rather answer with a hard edge than with a namespace.
There is no setup
This used to be an afternoon of host preparation: install Cloud Hypervisor, install
virtiofsd, sort out EFI firmware, possibly build a direct-boot kernel, then create a
container dataset and seed a template into it by hand.
HosterOS does all of it. The virtualisation stack — QEMU and Cloud Hypervisor — is installed into the system image when the ISO is built, so it lands on the machine offline, during the install. The encrypted and unencrypted container datasets are part of the standard dataset hierarchy the installer creates. Firmware boot is the default and needs nothing from you.
If you find a guide telling you to install a hypervisor before you can use microVMs, it predates HosterOS.
The lifecycle is the one you already know
hoster microvm mirrors hoster vm, deliberately. Same verbs, same shape, same
retention rules:
hoster microvm template pull debian13
hoster microvm deploy --name demo-app
hoster microvm list
hoster microvm status demo-app
hoster microvm console demo-app
hoster microvm stop demo-app
hoster microvm destroy demo-app
Templates, snapshots, replication and disaster-recovery backups are there too —
hoster microvm template pull, snapshot create, replicate, dr-backup — and behave
the way their VM counterparts do. Choosing between a VM and a microVM is a workload
decision, not a second platform to learn.
Take a screenshot of `hoster microvm list` next to `hoster vm list` on the same host, to show the two guest types managed side by side.
First, pull a template
MicroVMs clone from templates exactly the way VMs do, and they have their own catalogue
and their own set of commands. A template has to be on the node before anything can
be deployed from it — including debian13, which is only the default name, not
something that arrives with the install.
hoster microvm template list-online # what the repository publishes
hoster microvm template pull debian13 # bring it down into a container dataset
hoster microvm template list # what this node already has
Flag on pull |
What it does |
|---|---|
--parent-dataset |
Which container dataset to put it in |
--link-only |
Print only the download URL, for fetching through your own mirror |
--force |
Re-download even when the local copy is already up to date |
The Downloads page lists the same microVM catalogue with direct archive links, alongside the VM images. To build one of your own, see Building your own template.
Keeping templates in step
Two more commands matter once there is more than one dataset or more than one node:
hoster microvm template sync --check # between container datasets on this host
hoster microvm template replicate --check # from cluster peers to this host
Both take --check to show what they would do without doing it. In a cluster the
scheduler runs the replication for you on a schedule, so a node is not missing the
template you are about to deploy from; these are the manual equivalents.
Deploying one
hoster microvm deploy --name demo-app --compose-file ./compose.yaml
--template defaults to debian13 — the one pulled above — and --compose-file
copies your compose file straight into the guest’s /data/compose.yaml as it is built,
so once the template is local a deploy is the only command you run.
| Flag | Default | Notes |
|---|---|---|
--template |
debian13 |
Container-dataset template to clone |
--compose-file |
— | Copied to /data/compose.yaml in the new guest |
--cpus |
2 |
|
--ram |
2G |
|
--os-disk-size |
30G |
Absolute size for disk0.img |
--disk-expand |
— | Grow the cloned disk by an amount instead, e.g. 20G |
--parent-dataset |
first container dataset | Which container dataset to build in |
--bridge |
the internal bridge | |
--boot-mode |
firmware |
kernel switches to direct-kernel boot |
--host-device |
— | PCI device to pass through, by BDF or sysfs path |
The two deploy commands do not name their flags the same way. A VM takes
--os-template(with--templateas an alias),--cpu-cores,--cpu-socketsand--cpu-threads; a microVM takes--templateand a single--cpus. The same is true oftemplate pull: the VM version has a--debugflag that prints the shell commands instead of running them, and the microVM version does not. Worth knowing before you copy a command from one page to the other.
Firmware boot, or direct kernel
firmware is the default and is what you want. --boot-mode kernel boots a kernel
image directly — faster still, at the cost of caring about the image and its command
line, which default to /opt/hoster/firmware/vmlinux.bin and
console=ttyS0 root=/dev/vda1 rw. Reach for it when boot latency is the thing you are
optimising, not before.
Where your workload lives
Deploying demo-app clones the template into a container dataset and creates a
directory on the host, which is mounted inside the guest as /data:
<container dataset mountpoint>/demo-app/data → /data
Before start, the guest looks for a compose file at one of:
/data/docker-compose.yml
/data/docker-compose.yaml
/data/compose.yaml
The raw disk holds the guest OS and the Docker daemon’s own storage. /data is for the
compose file and your application’s data — which means the thing you care about keeping
is on the host side of a mount, where you can see it, back it up, and hand it to a
different guest.
Take a screenshot of a microVM's /data directory on the host next to `hoster microvm status` for the same guest, showing the compose file and the running state together.
Extra mounts
hoster microvm mount add demo-app ...
hoster microvm mount update demo-app ...
hoster microvm mount remove demo-app ...
Mounts come in two kinds: internal, for paths that live inside the container dataset alongside the guest, and external, for paths elsewhere on the host — a LeilFS path, a bulk data volume, anything the workload needs but should not own.
PCI passthrough
hoster microvm pci list demo-app
hoster microvm pci add demo-app <device>
hoster microvm pci remove demo-app <device>
Devices have to be reserved for guests before any of this — bound to vfio-pci at boot
rather than claimed by the host. The installer does that if you selected them on
screen 9, which also explains why
selecting a GPU pulls in its audio function, and covers the laptop and mini-PC case
where a discrete GPU shares an IOMMU group with a non-ACS root port.
Do that at install time where you can. It means the bindings are in the initramfs from first boot and the host never briefly claims the device on its way up.
When to use which
| Virtual machine | MicroVM | |
|---|---|---|
| Hypervisor | QEMU | Cloud Hypervisor |
| Boots in | seconds | a fraction of that |
| Workload | an operating system you administer | containers, from a compose file |
| Isolation | its own kernel | its own kernel |
| Managed by | hoster vm |
hoster microvm |
Both give you a kernel boundary. Choose a microVM when the unit of work is a compose stack and you want it to start quickly; choose a VM when the unit of work is a machine.
Next
- Your first VM — the same lifecycle for classic guests, if you have not run one yet.
- Changing a guest after deploy — CPU, RAM, mounts and passthrough after the fact, where microVMs have commands VMs do not.
- Deploying Control Center — the first microVM most people run, and a worked example of a compose workload.
- Snapshots, replication and the scheduler — the same automation covers microVMs, including per-guest DR targets.
- HosterOS installation — including the passthrough screen, where devices are reserved for guests.
Something unclear on this page?
Ask about this specific page and we will come back to you. Your question arrives with a link to it, so you do not have to describe where you were.