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 complete vmlab manual — every block, verb and API, cross-linked and searchable.

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

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