vmlab

Alpha software (v0.1.0) — vmlab is under active development.

Expect frequent breaking changes to labs, templates, and the CLI.

Declarative VM labs · QEMU/KVM

Orchestrate virtual machine labs from your terminal.

vmlab turns a single vmlab.wcl into a running fleet of VMs — machines, networks, and provisioning, wired automatically. Boot, snapshot, and tear down complex topologies with one command.

Open source · MIT · Linux, or Windows 11 via WSL 2 or Docker

vmlab.wclwcl
import <vmlab.wcl>

lab "demo" {

  segment "lan" {
    subnet = "10.81.0.0/24"
    nat    = true                                  // guest egress
    forward { host_port = 12222 to = "alp:22" }    // host SSH → guest
  }

  vm "alp" {
    template = "ghcr.io/vmlabdev/vmlab-templates/alpine-3.23"
    memory   = 1GiB
    nic { segment = "lan" }
  }

  provision "scripts/setup.ws" { }   // wscript, typed & checked
}

A taste

From a single file to a running lab in one command.

The lab is the file: segments with built-in DHCP, DNS and NAT, VMs booting linked clones of a template — pulled from an OCI registry on first up if it isn't local. vmlab validate type-checks the whole lab (wscript included) before anything boots.

Capabilities

Everything a lab needs, in one binary.

No bridges, no root, no setup step — a per-user daemon pair starts on demand and the whole network fabric runs in userspace.

Declarative labs

A lab {} block declares VMs and the networks between them. Hardware comes from guest OS profiles with clear precedence, so most VMs are a couple of lines — vmlab validate checks it all before boot.

Powered by QEMU/KVM

Runs x86_64, aarch64, and riscv64 guests from the same tool — KVM-accelerated natively, emulated across arches. No KVM? It falls back to TCG with a loud warning.

Userspace networking

Per-lab virtual switches with DHCP, DNS, NAT, routes, port forwards and L3 filtering — all declared in the lab, no taps, no CAP_NET_ADMIN, no manual wiring.

Snapshots

Capture a single VM or the whole lab, then roll back to any snapshot in seconds.

Guests without networking

Run commands and copy files over the QEMU guest agent — no network path to the VM required, so automation works before the guest is even configured.

OCI distribution

Push templates to any OCI registry as chunked, multi-arch artifacts; reference a registry ref straight from a lab and vmlab up pulls it on demand.

GUI automation & vision

Keystrokes, mouse, screenshots, image matching and OCR — script installers and GUI flows headlessly, even where no agent can run.

wscript provisioning

Provision scripts and event handlers drive guests through a typed API, compiled and type-checked at validate time — handle sysprep, wait for ready, gate the next step on it.

Linked-clone templates

Build a sealed qcow2 template once from installer media; labs boot copy-on-write clones, so templates stay immutable and labs stay small on disk.

Reference

The manual

The reference is published as a wskill — a self-contained WCL model projected into a readable book, a Claude Code skill, an overview deck, and a hands-on training course.

vmlab

A declarative QEMU/KVM VM-lab orchestrator: labs and virtual networks declared in WCL, reusable disk templates built locally or distributed over OCI registries, and guest automation written in wscript.

Read the manual · deck · course

Getting started

Install it and boot your first lab.

Needs /dev/kvm (on WSL 2 enable nested virtualisation). Or skip the install and run the container image with only --device /dev/kvm: docker run --rm -it --device /dev/kvm ghcr.io/vmlabdev/vmlab.

  1. Install the CLI

    curl -fsSL https://vmlab.io/install.sh | sh

  2. Write a lab, then validate it

    vmlab validate

  3. Boot it

    vmlab up