
holos v0.6.3
Declarative KVM/QEMU VM orchestration tool using YAML compose files. Manages multi-VM stacks with cloud-init, SSH, PCI passthrough, and image verification without libvirt or XML.
Docker compose for KVM. Define multi-VM stacks in one YAML file. No libvirt, no XML, no distributed control plane.
Website and docs: https://zeroecco.github.io/holos/
The primitive is a VM, not a container. Every workload instance gets its own kernel boundary, qcow2 overlay, cloud-init seed, and generated SSH access.
Start here
Run VMs on a Linux host with /dev/kvm, QEMU, and a cloud-init seed builder.
See host requirements. macOS builds support authoring,
image downloads, and validation; they cannot run KVM VMs.
Install
Pre-built binaries are attached to every GitHub release:
This example installs the Linux x86-64 build. It uses curl, tar,
sha256sum, and the GitHub CLI (gh) for provenance verification. For other
platforms, choose the matching archive on the release page.
(
set -e
TAG=v0.7.1
ASSET=holos_${TAG#v}_Linux_x86_64.tar.gz
BASE=https://github.com/zeroecco/holos/releases/download/$TAG
curl -fLO $BASE/$ASSET
curl -fLO $BASE/checksums.txt
grep " $ASSET$" checksums.txt | sha256sum -c -
gh attestation verify $ASSET --repo zeroecco/holos
sudo tar -xz -C /usr/local/bin -f $ASSET holos
holos version
holos doctor
)
Release pages include SHA-256 checksums and GitHub artifact attestations for signed provenance. Verify both before installing binaries on production hosts.
Or, from a checkout of this repository with Go 1.26 installed, build from source:
go build -o bin/holos ./cmd/holos
export PATH="$PWD/bin:$PATH"
holos doctor
Try one VM
Use a fixed name so every command below works as written:
holos run --name try-holos alpine
holos exec -w 5m try-holos
You are now in the guest. Run cat /etc/os-release, then exit to return to
the host. From the host:
holos stop try-holos # keep the guest disk
holos start try-holos
holos exec try-holos
Exit the guest again, then remove the disposable VM:
holos down try-holos # deletes its guest disk
Run a web service
Create an empty directory and save this as holos.yaml:
name: hello
services:
web:
image: ubuntu:noble
ports:
- "8080:80"
cloud_init:
packages: [nginx]
write_files:
- path: /var/www/html/index.html
content: "hello from holos\n"
runcmd:
- systemctl restart nginx
From that directory:
holos up
holos exec -w 5m web -- sudo cloud-init status --wait
curl --fail localhost:8080
Expect hello from holos. The wait matters: up starts the VM, but nginx is
installed during first boot. If provisioning fails, read holos logs web.
Daily use
Inside a project directory:
holos exec web # guest shell; exit returns to the host
holos logs web # boot and provisioning logs
holos stop web # keep its disk
holos start web
holos up --dry-run # preview changes after editing holos.yaml
holos help exec # syntax and options
Use an instance name such as web-0 when a service has multiple replicas.
Changes that replace or remove a VM require holos up --recreate; check the
preview first because replacement deletes that VM's root disk. Named volumes
survive. See the update guide
before updating projects created by an older release.
When finished with this disposable stack:
holos down hello
stop preserves instance disks. down deletes them; named volumes remain until
explicitly removed. See the CLI guide for snapshots, volumes,
image locks, and systemd setup.
Docs
- Website: landing page and rendered docs.
- CLI guide: ad hoc VMs,
exec, systemd install, virsh import, anddoctor. - Compose file: services, volumes, healthchecks, networking, PCI passthrough, Dockerfile provisioning, and defaults.
- JSON Schema: editor completion and validation for
holos.yaml. - Examples: runnable and template stacks with README-style explanations.
- Missing features: prioritized gaps that fit holos' single-host KVM compose goal.
- Development: build, test, host requirements, and release process.
- Security policy: supported versions and private reporting.
- Threat model / hardening: image verification, state permissions, locks, and operational guidance.
- Contributing: build, test, style, and PR conventions.
Host Requirements
- Linux with
/dev/kvm qemu-system-x86_64qemu-img- One of
cloud-localds,genisoimage,mkisofs, orxorriso - OVMF / edk2-ovmf firmware for UEFI or PCI passthrough
sshforholos execand healthchecks
Run holos doctor to check the host.
Troubleshooting
Permission denied opening /dev/kvm
Check id -nG and ls -l /dev/kvm. On hosts where the device belongs to the
kvm group, add your user with sudo usermod -aG kvm "$USER", then log out
and reconnect. Existing shells keep their old group membership. Run
holos doctor again from the new session.
SSH resets on first boot
kex_exchange_identification: read: Connection reset by peer usually means
cloud-init is still regenerating host keys and restarting sshd. holos exec
waits up to 60s by default, but very slow first boots may need another retry or
holos exec -w 5m <project>.
Console shows Login incorrect
The serial console may attempt autologin before cloud-init creates the user.
Wait for cloud-init ... finished in the console log, then use holos exec.
Cloud images generally do not ship with a console password, and holos does not
add one.
up fails on macOS
KVM is a Linux kernel feature. macOS binaries are useful for authoring and
offline commands, but holos up and holos run must execute on a Linux KVM
host.
Non-Goals
holos is not Kubernetes. It does not try to solve multi-host clustering, live migration, service meshes, overlay networks, schedulers, CRDs, or control plane quorum.
The goal is to make KVM workable for single-host stacks without importing the operational shape of Kubernetes.
License
Licensed under the Apache License, Version 2.0. See
NOTICE for attribution.