Host Requirements

This page lists the requirements for running mvm-ctrl as a bare-metal API server.

OpenSSH

The host must have OpenSSH installed and running. mvm-ctrl uses SSH for secure communication with sandboxes and for tunneling connections.

Install:

# Debian / Ubuntu
sudo apt install openssh-server

# Fedora / RHEL
sudo dnf install openssh-server

# Arch
sudo pacman -S openssh

Enable and start the service:

sudo systemctl enable --now sshd

Verify it is running:

systemctl status sshd

KVM and libvirtd

The host must support hardware virtualization (KVM) and have libvirt installed. KVM provides the hypervisor layer and libvirtd manages virtual machine lifecycle.

Check KVM support:

# Verify CPU virtualization extensions are available
egrep -c '(vmx|svm)' /proc/cpuinfo
# A non-zero result means KVM is supported

# Load the KVM module if not already loaded
sudo modprobe kvm
sudo modprobe kvm_intel  # Intel CPUs
sudo modprobe kvm_amd    # AMD CPUs

Install:

# Debian / Ubuntu
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients

# Fedora / RHEL
sudo dnf install qemu-kvm libvirt

# Arch
sudo pacman -S qemu-full libvirt

Enable and start the service:

sudo systemctl enable --now libvirtd

Add your user to the libvirt group:

sudo usermod -aG libvirt $(whoami)

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

Verify it is running:

systemctl status libvirtd
virsh list --all

Firecracker (optional)

Firecracker is only required if you plan to use the Firecracker microVM backend. It provides lightweight KVM-based virtualization with minimal overhead. Firecracker depends on KVM, so the KVM and libvirtd section above must be satisfied first.

Install the Firecracker binary

Download the latest release from GitHub and place it on your PATH:

# Download and extract (update the version as needed)
curl -LO https://github.com/firecracker-microvm/firecracker/releases/download/v1.5.2/firecracker-v1.5.2-x86_64.tgz
tar -xf firecracker-v1.5.2-x86_64.tgz
sudo cp release-v1.5.2-x86_64/firecracker /usr/local/bin/
sudo chmod +x /usr/local/bin/firecracker

Verify installation:

firecracker --version

Install a kernel image and root filesystem

Firecracker boots a Linux kernel and root filesystem directly. Place them in a well-known location:

sudo mkdir -p /usr/share/firecracker/resources

# Example: download a minimal kernel and rootfs
curl -Lo /tmp/hello-vmlinux.bin \
  https://s3.amazonaws.com/spec.ccfc.min/img/hello/kernel/hello-vmlinux.bin
curl -Lo /tmp/hello-rootfs.ext4 \
  https://s3.amazonaws.com/spec.ccfc.min/img/hello/fsfiles/hello-rootfs.ext4

sudo mv /tmp/hello-vmlinux.bin /usr/share/firecracker/resources/
sudo mv /tmp/hello-rootfs.ext4 /usr/share/firecracker/resources/

The guest rootfs image must have the following:

  • An SSH server installed and configured to start on boot
  • Root login enabled (or an appropriate user configured)
  • Network interface configuration compatible with the TAP IP settings

Configure TAP networking

Firecracker VMs communicate over TAP devices. heyvm creates and tears down TAP devices automatically, but the underlying ip and iptables commands require root privileges. heyvm runs these through sudo -n (non-interactive), so sudo must be able to execute them without prompting for a password. If your sudo credential cache has expired, heyvm will fail immediately with a clear error rather than hanging.

Recommended: passwordless sudo for networking commands

Create a sudoers drop-in file that allows your user to run only the specific commands heyvm needs:

sudo visudo -f /etc/sudoers.d/heyvm-firecracker

Add the following (replace your-username with your actual username):

your-username ALL=(root) NOPASSWD: /usr/sbin/ip, /usr/sbin/iptables, /usr/sbin/sysctl

If your distro installs these binaries elsewhere, find the correct paths first:

which ip iptables sysctl

Verify it works without a password prompt:

sudo -n ip link show

If this prints your network interfaces without asking for a password, you are set.

Alternative: cache credentials before running heyvm

If you prefer not to configure passwordless sudo, you can cache your credentials manually before each session:

sudo -v
heyvm test-firecracker

The cached credentials typically last 5–15 minutes depending on your system's timestamp_timeout setting.

Verify /dev/kvm access

Firecracker talks directly to /dev/kvm. Make sure the current user has read-write access:

ls -l /dev/kvm
# If permission denied:
sudo usermod -aG kvm $(whoami)

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

HeyVM systemd service

To run heyvm as a long-lived background service, install the provided systemd unit file. This ensures the API server starts automatically on boot and restarts on failure.

Install the unit file:

sudo cp mvm-ctrl/install/heyvm.service /etc/systemd/system/heyvm.service

The default unit file looks like this:

[Unit]
Description=HeyVM API Server - Microsandbox Manager
After=network-online.target libvirtd.service
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/heyvm --api
Restart=on-failure
RestartSec=5

# Run as your user
User=<your-user>
Group=<your-user>

# Environment variables - core
Environment=MVM_DATA_DIR=/home/<your-user>/.heyvm
Environment=MSB_API_KEY=
Environment=HEYO_ENV=production

# API / networking
Environment=API_HOSTNAME=
Environment=JWT_SECRET=
Environment=JWT_AUDIENCE=

# Auth
Environment=AUTH_SERVER_URL=https://auth.heyo.computer
Environment=HEYO_CLOUD_URL=https://server.heyo.computer

# Backend identification
Environment=BACKEND_SERVER_ID=

# firecracker-containerd: use a privileged firecracker-ctr wrapper when heyvm
# itself runs unprivileged. Requires a matching sudoers rule for the real
# firecracker-ctr binary.
Environment=HEYVM_FIRECRACKER_CONTAINERD_CTR_COMMAND=sudo -n firecracker-ctr

# S3 archival (optional)
Environment=S3_ENABLED=false
Environment=S3_BUCKET=
Environment=AWS_REGION=
Environment=AWS_ENDPOINT_URL=

# Relay (optional)
Environment=HEYO_RELAY_URL=

# Override with a file for secrets (recommended)
EnvironmentFile=-/etc/heyvm/env

# Hardening
# Keep NoNewPrivileges disabled when using the firecracker-containerd sudo
# wrapper above; `sudo` needs setuid privilege escalation to work.
NoNewPrivileges=false
ProtectSystem=strict
ReadWritePaths=/home/<your-user>/.heyvm /tmp
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Edit the unit file to match your environment. At a minimum, update the User, Group, ExecStart, and ReadWritePaths directives to reflect your system user and heyvm install path. Fill in the required environment variables (MSB_API_KEY, API_HOSTNAME, JWT_SECRET, JWT_AUDIENCE, BACKEND_SERVER_ID). If you use the firecracker_containerd backend while running heyvm unprivileged, keep HEYVM_FIRECRACKER_CONTAINERD_CTR_COMMAND=sudo -n firecracker-ctr and add a matching sudoers rule for the real firecracker-ctr binary.

sudo nano /etc/systemd/system/heyvm.service

For secrets, the recommended approach is to use the environment file override instead of putting values directly in the unit file:

sudo mkdir -p /etc/heyvm
sudo nano /etc/heyvm/env

Add your secrets one per line in KEY=VALUE format:

MSB_API_KEY=your-api-key
JWT_SECRET=your-jwt-secret
JWT_AUDIENCE=your-jwt-audience
BACKEND_SERVER_ID=your-server-id
HEYVM_FIRECRACKER_CONTAINERD_CTR_COMMAND=sudo -n firecracker-ctr

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable --now heyvm

Verify it is running:

systemctl status heyvm
journalctl -u heyvm -f

LXC (optional)

LXC is only required if you plan to run Linux containers through mvm-ctrl. It can be skipped if you only need VM-based sandboxes.

Install:

# Debian / Ubuntu
sudo apt install lxc lxc-utils

# Fedora / RHEL
sudo dnf install lxc lxc-extra

# Arch
sudo pacman -S lxc

Enable and start the service:

sudo systemctl enable --now lxc

Verify it is working:

lxc-checkconfig