Run other operating systems
Boot a Linux distribution, a BSD, or other x86-64 OS images as a QEMU/KVM guest inside your container.
Run full, hardware-accelerated virtual machines inside your container - your own kernel, your own operating system, on your own bare metal.
Hoody containers are fast and lightweight, but sometimes you need a full virtual machine: a different kernel, a different operating system, or a workload that expects real VM hardware. On rented and dedicated servers you can enable KVM passthrough and run QEMU/KVM virtual machines directly inside your container, using the host CPU’s hardware virtualization extensions.
Run other operating systems
Boot a Linux distribution, a BSD, or other x86-64 OS images as a QEMU/KVM guest inside your container.
Virtualization-based workloads
Run workloads that expect a real VM - test kernels and kernel modules, or run VM-based CI.
A different kernel
Need a kernel version or configuration the host does not provide? Boot your own inside a VM.
Hardware-accelerated
KVM uses the CPU’s VT-x / AMD-V extensions, so guests run at near-native CPU performance - not slow emulation.
Use a rented or dedicated server, sized. Free-tier containers cannot enable KVM. The target must also carry a size: a subserver slice needs memory, CPU and disk assigned, while a dedicated (bare-metal) server needs memory and CPU - it has no per-slice disk figure to set. An unsized target is rejected. If you do not have one yet, rent a server.
Enable kvm for the container. It is a simple true/false setting, off by default. The canonical name is kvm; dev_kvm is accepted as an alias.
You can turn it on at creation - pass kvm: true in the create request (or --kvm on the CLI) - or later, on a stopped container, with the dedicated toggle endpoint:
PUT /api/v1/containers/{id}/kvm{ "kvm": true }The container must be stopped to change this setting - the toggle is rejected on any container that is not fully stopped, including one still being created.
On a rented server (a subserver slice), kvm: true at creation normally does everything: the create response comes back with kvm: true, the grant is provisioned, and /dev/kvm attaches when the container first starts. If the automatic enable cannot complete, the outcome depends on how the container was built - one claimed from the ready pool comes back kvm: false with a kvm_note (enable it with the toggle above once it is stopped), while a fresh build whose slice cannot be provisioned for KVM is rejected outright, with nothing created; retry on a KVM-capable, sized slice.
On a dedicated (bare-metal) server, creating with kvm: true always comes back kvm: false with a kvm_note, and this is by design rather than a failure. A build placed directly on a physical host is dispatched asynchronously, so there is no point during the create at which the KVM limits can be written and the device attached before the container’s first start. The container is created with KVM off and you turn it on with the toggle above once it is stopped - one extra call, and the toggle fully supports bare-metal placement. Expect this every time on a dedicated server; it is not an error and nothing needs retrying.
Start the container. The /dev/kvm grant is applied when the container starts.
Verify /dev/kvm is present inside the container:
ls -l /dev/kvm# crw-rw-rw- 1 root root ... /dev/kvm - present, world-readable/writable (mode 0666)The node is world-readable/writable (mode 0666), so you can run QEMU as a non-root user inside the container.
To turn it back off, stop the container, set kvm to false (same endpoint), and start it again. The device is removed and the container returns to a standard, VM-free state.
When you copy a container, KVM is a fresh decision for the copy - the grant never transfers from the source. A copy of a KVM container starts KVM-off unless you ask for it, and a copy of an ordinary container can be granted KVM on the spot. This keeps the copy’s capability tied to its own server, not the original’s.
To grant the copy /dev/kvm, pass kvm: true on the copy request (or --kvm on the CLI copy):
POST /api/v1/containers/{id}/copy{ "target_project_id": "...", "kvm": true }The same rules apply to the copy as to any other container: the target must be a rented or dedicated server (never the free tier, or the copy is refused with a 403), it must be sized (an unsized target is a 400 rather than a 403), and a scoped token needs the containers.features.kvm permission.
On a rented server the copy’s /dev/kvm is attached before it first starts, exactly as with a fresh container. On a dedicated (bare-metal) target the copy behaves like a fresh build there: it comes back kvm: false with a kvm_note, for the same reason, and you enable it with the toggle once the copy is stopped.
With /dev/kvm available, any KVM-based tool works. A minimal check with QEMU (Debian/Ubuntu example):
# boot a guest with KVM acceleration - QEMU is already installedqemu-system-x86_64 -enable-kvm -m 2048 -cdrom your-os.isoYou do not need to install QEMU. Any container created with the Hoody Kit (the default) already
has the VM runtime: qemu-system-x86 and qemu-system-gui, qemu-utils, OVMF UEFI firmware
including the Secure Boot pair, passt for unprivileged guest networking, virtiofsd for file
sharing, and swtpm for a virtual TPM. Reach for apt-get only if you created the container with
hoody_kit: false, or built it from a base image that is not Debian 13 on amd64.
The runtime and the grant are two separate things, and they arrive by different routes: the packages
ride the Hoody Kit, while /dev/kvm is the per-container grant you enabled above. A container with
the packages but no grant simply has no /dev/kvm to accelerate against.
If -enable-kvm is accepted, you are running a hardware-accelerated virtual machine inside your container.
For more on how Hoody isolates workloads, see platform security. To get a server that supports KVM, see renting servers.