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 machines — VMs, containers, 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"
    arch     = "x86_64"                            // multi-arch ref: pick one
    memory   = 1GiB
    nic { segment = "lan" }

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

  container "web" {                    // an OCI image, run as a micro-VM
    image = "nginx:1.27"
    nic { segment = "lan" }
  }
}

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 — and OCI containers running as micro-VMs on the same wire. 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

vmlab's own guest agent rides a virtio-serial port, so exec, file copy, shells and readiness never touch the guest's network — automation works before the guest is even configured, and in both VMs and containers.

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.

Containers as lab machines

A container {} block runs an OCI image in its own micro-VM: same segments, same DNS, same snapshots and the same agent as a VM — a real kernel boundary, not a namespace.

Playbook convergence

Declare config-weave playbooks inside the machine they converge. vmlab up applies them, reboots when a step demands it, and vmlab playbook check reports drift without changing anything.

Browser console

vmlab-web serves the whole lab from one port: live desktops, terminals, a visual topology designer, a file editor, playbook authoring and log streams — over the same API the CLI uses.

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, which starts the web console on port 7878: docker run --rm -p 7878:7878 --device /dev/kvm ghcr.io/vmlabdev/vmlab. Append a command to get the CLI instead.

  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