Skip to content

tsirysndr/vmx

Repository files navigation

vmx

ci JSR

A powerful command-line tool and HTTP API for managing and running headless virtual machines using QEMU. Built with Deno and TypeScript, vmx provides a Docker-like experience for VM management with OCI registry support.

Preview

Features

🚀 Core Functionality

  • Headless VM Management - Run VMs in the background without GUI overhead
  • QEMU Integration - Leverages QEMU for robust virtualization on both x86_64 and ARM64 architectures
  • Docker-like CLI - Familiar commands for VM lifecycle management (run, start, stop, ps, rm, logs, inspect, etc.)
  • Configuration Files - TOML-based configuration for reproducible VM setups
  • Multiple Input Sources - Boot from local ISOs, remote URLs, or OCI registry images

📦 OCI Registry Support

  • Pull & Push - Store and retrieve VM images from OCI-compliant registries (GitHub Container Registry, Docker Hub, etc.)
  • Image Management - List, tag, and remove local VM images
  • Authentication - Secure login/logout for private registries with password from stdin or interactive prompt
  • Cross-platform - Automatic architecture detection and handling (amd64/arm64)

🐧 Quick Start Linux Distributions

  • Ubuntu - Quick shortcuts like vmx ubuntu with automatic download
  • Debian - Support for vmx debian with cloud-init ready images
  • Fedora - Run vmx fedora:43 with CoreOS and Server editions
  • Alpine Linux - Lightweight vmx alpine for minimal setups
  • AlmaLinux - Enterprise-ready with vmx alma
  • Rocky Linux - RHEL-compatible via vmx rocky
  • NixOS - Declarative systems with vmx nixos
  • Gentoo - Source-based distributions with vmx gentoo
  • Fedora CoreOS - Container-optimized OS with automatic version detection

All distributions automatically download the appropriate image for your architecture (ARM64/x86_64) and cache for subsequent runs.

🌐 Networking

  • Bridge Networking - Create and manage network bridges for VM connectivity
  • Port Forwarding - Easy SSH and service access with flexible port mapping (e.g., -p 2222:22,8080:80)
  • Multiple Network Modes - Support for various QEMU networking configurations
  • Automatic Bridge Setup - Creates network bridges automatically when needed

💾 Storage & Volumes

  • Volume Management - Create, list, inspect, and delete persistent volumes
  • Multiple Disk Formats - Support for qcow2 and raw disk images
  • Automatic Provisioning - Volumes are created automatically from base images or attached to VMs
  • Flexible Sizing - Configurable disk sizes for different workloads (e.g., -s 40G)
  • Volume Attachment - Attach volumes to VMs with -v flag

☁️ Cloud-Init Support

  • Seed Image Creation - Interactive vmx seed command to generate cloud-init configuration
  • User Data & Meta Data - Full support for cloud-init user-data and meta-data
  • SSH Key Injection - Automatically configure SSH authorized keys
  • Custom User Setup - Define default user, shell, and sudo permissions
  • Instance Configuration - Set hostname and instance ID for cloud environments

🔧 Advanced Features

  • Detached Mode - Run VMs in the background as daemon processes with -d flag
  • Live Logs - Stream VM output and follow logs in real-time with -f flag
  • VM Inspection - Detailed information about running and stopped VMs
  • Resource Configuration - Customizable CPU (type and cores), memory, and disk settings
  • ARM64 & x86_64 Support - Native support for both architectures with UEFI firmware
  • Install Mode - Persist changes to VM disk image with --install flag
  • Automatic Caching - Downloaded ISOs and images are cached locally for faster subsequent runs

🌍 HTTP API

  • RESTful API - Full-featured HTTP API for programmatic VM management
  • Bearer Authentication - Secure API access with token-based auth (auto-generated or custom via VMX_API_TOKEN)
  • Machines Endpoint - Create, start, stop, restart, and remove VMs via API
  • Images Endpoint - List and query VM images
  • Volumes Endpoint - Create, list, inspect, and delete persistent volumes
  • CORS Support - Cross-origin requests for web-based tools
  • Custom Port - Configure API server port with --port flag or VMX_API_PORT env var

Installation

# Install with Deno
 deno install -A -r -f -g jsr:@tsiry/vmx

Requirements

  • Deno runtime
  • QEMU installed on your system
    • macOS: brew install qemu
    • Linux: apt-get install qemu-system or yum install qemu-kvm

Quick Start

Initialize Configuration

Create a default VM configuration file:

vmx init

This creates a vmconfig.toml file with sensible defaults.

Run a VM from ISO

# From a local ISO file
vmx /path/to/ubuntu.iso

# Download and run from URL
vmx https://cdimage.ubuntu.com/releases/24.04/release/ubuntu-24.04.3-live-server-arm64.iso

# From OCI registry
vmx ghcr.io/tsirysndr/ubuntu:24.04

Quick Start with Linux Distributions

Use distribution shortcuts to quickly spin up VMs:

# Ubuntu
vmx ubuntu

# Debian  
vmx debian

# Fedora
vmx fedora
vmx fedora-coreos

# Alpine Linux
vmx alpine

# AlmaLinux
vmx alma

# Rocky Linux
vmx rocky
# NixOS
vmx nixos

# Gentoo
vmx gentoo

These shortcuts automatically download the appropriate cloud-ready or installation images for your architecture (ARM64 or x86_64).

Pull and Run from Registry

# Pull an image
vmx pull ghcr.io/tsirysndr/ubuntu:24.04

# Run the image
vmx run ghcr.io/tsirysndr/ubuntu:24.04

# Run with custom resources
vmx run ghcr.io/tsirysndr/ubuntu:24.04 -m 4G -C 4 -d

Usage

VM Lifecycle Management

# List running VMs
vmx ps

# List all VMs (including stopped)
vmx ps --all

# Start a VM
vmx start my-vm

# Stop a VM
vmx stop my-vm

# Restart a VM
vmx restart my-vm

# Remove a VM
vmx rm my-vm

# View VM logs
vmx logs my-vm

# Follow logs in real-time
vmx logs -f my-vm

# Inspect VM details
vmx inspect my-vm

Image Management

# List local images
vmx images

# Pull from registry
vmx pull ghcr.io/tsirysndr/ubuntu:24.04

# Push to registry
vmx push ghcr.io/tsirysndr/my-vm:latest

# Tag an image
vmx tag my-vm ghcr.io/tsirysndr/my-vm:v1.0

# Remove an image
vmx rmi ghcr.io/tsirysndr/ubuntu:24.04

Registry Authentication

# Login to registry
vmx login -u username ghcr.io

# Login with password from stdin
echo "password" | vmx login -u username ghcr.io

# Logout
vmx logout ghcr.io

Volume Management

# List volumes
vmx volumes

# Create and attach a volume to VM
vmx run ubuntu -v my-data

# Create volume with custom size
vmx run ubuntu -v my-data -s 50G

# Inspect a volume
vmx volume inspect my-data

# Remove a volume
vmx volume rm my-data

Cloud-Init Configuration

# Create a cloud-init seed image interactively
vmx seed

# Create with custom output path
vmx seed my-seed.iso

# Run VM with cloud-init seed
vmx ubuntu --cloud --seed seed.iso

# The seed command will prompt for:
# - Instance ID
# - Hostname
# - Default username
# - User shell
# - Sudo permissions
# - SSH authorized keys

Advanced Options

# Run with custom resources
vmx run ubuntu:24.04 \
  --cpu host \
  --cpus 4 \
  --memory 4G \
  --detach

# With multiple port forwards (SSH and HTTP)
vmx run ubuntu:24.04 -p 2222:22,8080:80

# With bridge networking
vmx run ubuntu:24.04 --bridge br0

# With persistent disk and install mode
vmx ubuntu:24.04 \
  --image /path/to/disk.img \
  --size 40G \
  --disk-format qcow2 \
  --install

# With cloud-init and volume
vmx run ubuntu:24.04 \
  --cloud \
  --seed seed.iso \
  -v data \
  -s 50G \
  -d

Configuration File

The vmconfig.toml file allows you to define default VM settings:

[vm]
iso = "https://cdimage.ubuntu.com/releases/24.04/release/ubuntu-24.04.3-live-server-arm64.iso"
cpu = "host"
cpus = 2
memory = "2G"
image = "./vm-disk.img"
disk_format = "raw"
size = "20G"

[network]
bridge = "br0"
port_forward = "2222:22"

[options]
detach = false

HTTP API

Start the API server:

# Start on default port (8889)
vmx serve

# Start on custom port
vmx serve --port 3000

# With custom API token
export VMX_API_TOKEN=your-secret-token
vmx serve

API Endpoints

Machines (VMs)

  • GET /machines - List all machines
  • GET /machines?all=true - List all machines including stopped
  • POST /machines - Create a new machine
  • GET /machines/:id - Get machine details
  • DELETE /machines/:id - Remove a machine
  • POST /machines/:id/start - Start a machine
  • POST /machines/:id/stop - Stop a machine
  • POST /machines/:id/restart - Restart a machine

Images

  • GET /images - List all images
  • GET /images/:id - Get image details

Volumes

  • GET /volumes - List all volumes
  • GET /volumes/:id - Get volume details
  • POST /volumes - Create a new volume
  • DELETE /volumes/:id - Remove a volume

API Authentication

All API requests require a Bearer token. The token is auto-generated on first run or can be set via the VMX_API_TOKEN environment variable:

# Auto-generated token (displayed on startup)
vmx serve

# Custom token
export VMX_API_TOKEN=your-secret-token
vmx serve

# Custom port
vmx serve --port 3000
# or
export VMX_API_PORT=3000
vmx serve

API requests using the Bearer token:

curl -H "Authorization: Bearer your-token" http://localhost:8889/machines

Example API Usage

# Create a machine
curl -X POST http://localhost:8889/machines \
  -H "Authorization: Bearer your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "ubuntu:24.04",
    "memory": "4G",
    "cpus": 4,
    "portForward": ["2222:22"],
    "volume": "data"
  }'

# Start a machine
curl -X POST http://localhost:8889/machines/{id}/start \
  -H "Authorization: Bearer your-token"

# List all machines
curl http://localhost:8889/machines \
  -H "Authorization: Bearer your-token"

# Create a volume
curl -X POST http://localhost:8889/volumes \
  -H "Authorization: Bearer your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "data",
    "size": "50G"
  }'

Architecture Support

vmx automatically detects and adapts to your system architecture:

  • x86_64 / amd64 - Full QEMU system emulation
  • ARM64 / aarch64 - Native Apple Silicon and ARM server support with UEFI firmware

Examples

Development Environment

# Quick start with Ubuntu
vmx ubuntu:24.04

# Or initialize with custom configuration
vmx init

# Edit vmconfig.toml to your needs
# Then start the VM
vmx

# SSH into the VM (with port forwarding configured)
ssh -p 2222 user@localhost

Cloud-Init Setup

# Create a cloud-init seed image
vmx seed

# Run Ubuntu with cloud-init
vmx ubuntu --cloud --seed seed.iso -p 2222:22 -d

# Wait for VM to boot and SSH in
ssh -p 2222 ubuntu@localhost

CI/CD Integration

# Pull a pre-configured image
vmx pull ghcr.io/company/test-env:latest

# Run tests in detached mode with volume for results
vmx run ghcr.io/company/test-env:latest -d -v test-results

# Execute tests and cleanup
vmx stop test-vm
vmx rm test-vm
vmx volume rm test-results

Multi-VM Setup

# Start database VM with persistent storage
vmx run postgres -d -p 5432:5432 -v pgdata -s 20G

# Start application VM with bridge networking
vmx run app -d -p 8080:8080 --bridge br0

# Start cache VM
vmx run redis -d -p 6379:6379

# List all running VMs
vmx ps

Quick Distribution Testing

# Test different distributions
vmx alpine -m 512M -C 1
vmx fedora-coreos 
vmx nixos-m 4G -C 2 
vmx rockylinux -p 2222:22 -d

License

Mozilla Public License 2.0 (MPL-2.0)

Copyright (c) 2025 Tsiry Sandratraina

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

Links

Sponsor this project

 

Packages