Skip to content

Create a Local VM on Linux (QEMU/libvirt)

On a Linux host you can run a meltcloud Nest or Machine as a local VM using QEMU/KVM, managed with libvirt.

VM Settings

SettingNestMachine
Architecturehost arch (amd64/arm64)host arch (amd64/arm64)
vCPU8+2+
RAM16 GB+4 GB+
Disk≥ 200 GB≥ 20 GB
NetworkingDefault (NAT)Default (NAT)
Nested virtualizationnot requiredoptional, required for Elastic Pools
Boot mediaNest installer .isoEnrollment Image .iso

Prerequisites

Install packages

Install libvirt and qemu-kvm for your distro. The following installs it on Ubuntu 24.04, where this guide was tested:

shell
sudo apt install qemu-kvm libvirt-daemon-system ovmf

Add your user to the libvirt group so you can manage VMs without root:

shell
sudo usermod -aG libvirt $USER

Log out and back in for the group change to take effect.

Start the default network

libvirt ships a default NAT network that provides DHCP and internet access. Make sure it is active:

shell
sudo virsh net-start default
sudo virsh net-autostart default

Copy the ISO

Create a directory for VM images and copy your .iso into it:

shell
# placed under /var/lib/libvirt so libvirt can traverse into it
sudo mkdir -p /var/lib/libvirt/melt-vms
sudo chown $USER:kvm /var/lib/libvirt/melt-vms

# Nest installer
cp /path/to/nest-installer-amd64.iso /var/lib/libvirt/melt-vms/
# Enrollment Image for Machines
cp /path/to/enrollment-image-amd64.iso /var/lib/libvirt/melt-vms/

Create the VM

shell
VMDIR=/var/lib/libvirt/melt-vms
ISO_PATH=$VMDIR/nest-installer-amd64.iso

# create the disk (adjust size as needed, minimum 200G)
qemu-img create -f qcow2 $VMDIR/melt-nest.qcow2 200G

# write the VM definition
cat > $VMDIR/melt-nest.xml << EOF
<domain type='kvm'>
  <name>melt-nest</name>
  <!-- RAM: 16 GB minimum -->
  <memory unit='GiB'>16</memory>
  <!-- CPU: 8+ vCPUs recommended -->
  <vcpu>8</vcpu>
  <os firmware='efi'>
    <type arch='x86_64'>hvm</type>
    <boot dev='hd'/>
    <boot dev='cdrom'/>
  </os>
  <features>
    <acpi/>
  </features>
  <cpu mode='host-passthrough'/>
  <devices>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <!-- adjust path if you changed the qemu-img command above -->
      <source file='$VMDIR/melt-nest.qcow2'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <disk type='file' device='cdrom'>
      <source file='$ISO_PATH'/>
      <target dev='sda' bus='sata'/>
      <readonly/>
    </disk>
    <interface type='network'>
      <source network='default'/>
      <model type='virtio'/>
    </interface>
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
  </devices>
</domain>
EOF

# define, start, and connect to the console
virsh define $VMDIR/melt-nest.xml
virsh start melt-nest --console
shell
VMDIR=/var/lib/libvirt/melt-vms
ISO_PATH=$VMDIR/enrollment-image-amd64.iso
# change the name to create multiple machines (e.g. worker1, worker2)
VM_NAME=worker1

# create the disk (adjust size as needed, minimum 20G)
qemu-img create -f qcow2 $VMDIR/$VM_NAME.qcow2 40G

# write the VM definition
cat > $VMDIR/$VM_NAME.xml << EOF
<domain type='kvm'>
  <name>$VM_NAME</name>
  <!-- RAM: 4 GB minimum -->
  <memory unit='GiB'>8</memory>
  <!-- CPU: 2+ vCPUs -->
  <vcpu>4</vcpu>
  <os firmware='efi'>
    <type arch='x86_64'>hvm</type>
    <boot dev='hd'/>
    <boot dev='cdrom'/>
  </os>
  <features>
    <acpi/>
  </features>
  <cpu mode='host-passthrough'/>
  <devices>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <!-- adjust path if you changed the qemu-img command above -->
      <source file='$VMDIR/$VM_NAME.qcow2'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <disk type='file' device='cdrom'>
      <source file='$ISO_PATH'/>
      <target dev='sda' bus='sata'/>
      <readonly/>
    </disk>
    <interface type='network'>
      <source network='default'/>
      <model type='virtio'/>
    </interface>
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
  </devices>
</domain>
EOF

# define, start, and connect to the console
virsh define $VMDIR/$VM_NAME.xml
virsh start $VM_NAME --console

Exit the console with Ctrl+5. To reconnect later:

shell
virsh console melt-nest

To clean up a VM:

shell
virsh destroy melt-nest
virsh undefine melt-nest --nvram

Next Steps

  • Nest: follow the on-screen TUI installer.
  • Machine: after it boots from the Enrollment Image it enrolls automatically and appears under Machines. Continue with Assign to a Machine Pool.

Troubleshoot

Nested virtualization not working

Nested virtualization is enabled by default on most recent Linux distributions. If it is not working, enable it manually:

shell
# Intel
echo "options kvm_intel nested=1" | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intel

# AMD
echo "options kvm_amd nested=1" | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_amd && sudo modprobe kvm_amd

Verify with:

shell
cat /sys/module/kvm_intel/parameters/nested   # or kvm_amd

The VM must also use <cpu mode='host-passthrough'/> (already included in the XML definitions above).

Other issues

If the VM has trouble booting or enrolling, check the Enrollment Images – Troubleshooting section.