A secure, unattended installer for the latest stable Cloud Hypervisor release on Debian 13 (Trixie) or newer, together with a small Alpine Linux VM demo.
The installer downloads the latest official Cloud Hypervisor static release, validates the downloaded ELF binary and host prerequisites, configures KVM access, prepares the system data directories, and installs Cloud Hypervisor system-wide.
The included demo script creates a persistent 100 MiB Alpine Linux root filesystem and boots it directly with Cloud Hypervisor using a custom Linux kernel built from the Cloud Hypervisor kernel configuration, together with a generated initramfs.
- Debian GNU/Linux 13 (Trixie) or newer
- Linux kernel 6.6 or newer
- x86_64 or aarch64
- Hardware virtualization enabled:
- Intel VT-x
- AMD-V
- Nested KVM
/dev/kvm/dev/net/tun- Root privileges, or
sudo
The installer checks the running kernel, CPU virtualization support on x86_64, /dev/kvm, and TUN/TAP availability before installation.
The installer automatically installs missing Debian packages required by the installation process:
aclbcbisoncoreutilscurldwarveselfutils-devfileflexgccgitgrepmakenftablesopenssl-devperlpkgconftar
It installs:
- Cloud Hypervisor
The official static release asset is selected according to the host architecture:
cloud-hypervisoron x86_64cloud-hypervisor-static-aarch64on AArch64
Make the installer executable and run it:
chmod +x install-cloud-hypervisor.sh
sudo ./install-cloud-hypervisor.shIf executed as a non-root user and sudo is available, the installer automatically re-executes itself with root privileges.
Root privileges are required because the installer manages the system-wide Cloud Hypervisor binary, KVM permissions, udev rules, and system data directories.
Cloud Hypervisor is installed system-wide under:
/usr/local/bin/cloud-hypervisor
The binary is installed as:
root:root
0755
It is therefore available through the normal system PATH.
Verify the installation with:
cloud-hypervisor --versionThe installer also executes the installed binary as the detected target user when the installer was started from a non-root session.
The installer creates the following hierarchy:
/var/lib/cloud-hypervisor-data/
├── base/
├── instances/
└── snapshots/
The directories are:
/var/lib/cloud-hypervisor-data
/var/lib/cloud-hypervisor-data/base
/var/lib/cloud-hypervisor-data/instances
/var/lib/cloud-hypervisor-data/snapshots
Permissions are:
/var/lib/cloud-hypervisor-data root:root 0755
/var/lib/cloud-hypervisor-data/base root:root 0755
/var/lib/cloud-hypervisor-data/instances root:root 0700
/var/lib/cloud-hypervisor-data/snapshots root:root 0700
/var/lib/cloud-hypervisor-data/base/
Intended for base VM images and other reusable VM assets.
/var/lib/cloud-hypervisor-data/instances/
Intended for VM-specific instance data.
/var/lib/cloud-hypervisor-data/snapshots/
Intended for VM snapshots.
When run through sudo, the installer detects the initiating user using SUDO_USER.
The target user is used primarily for:
- KVM access configuration
- non-root Cloud Hypervisor execution testing
Cloud Hypervisor itself is installed system-wide and is not placed in the user's home directory.
The installer verifies:
- CPU hardware virtualization on x86_64
/dev/kvmexists/dev/kvmis a character device- The target user can access
/dev/kvm
It creates the kvm group if necessary and configures:
/etc/udev/rules.d/99-kvm.rules
with:
KERNEL=="kvm", GROUP="kvm", MODE="0660"
The target user is added to the kvm group.
The installer also attempts to grant the target user immediate read/write access to /dev/kvm with an ACL, avoiding the need for a new login session when the ACL is available.
The installer verifies:
/dev/net/tun
If the device is missing, it attempts to load the tun kernel module.
Installation stops if TUN/TAP remains unavailable.
TUN/TAP support is required by the included Alpine demo because the demo creates a host TAP interface and attaches it to the VM.
The installer retrieves the latest stable Cloud Hypervisor release metadata from the official Cloud Hypervisor GitHub repository.
It then:
- Determines the latest release tag.
- Determines the host architecture.
- Selects the architecture-specific official static release asset.
- Downloads the release binary over HTTPS.
- Verifies that the downloaded file is an ELF executable.
- Verifies that its architecture matches the host.
- Checks static linking with
lddwhen available. - Installs the validated binary system-wide.
- Executes the installed binary and reports its version.
The installer does not use a SHA-256 checksum file because the installer source explicitly notes that Cloud Hypervisor's GitHub releases do not publish a SHA-256 checksum asset for the selected binary.
Therefore, the integrity checks performed by this installer are based on the official release asset URL, ELF/architecture validation, static-binary validation, and successful version execution.
The installer checks /proc/cpuinfo for:
vmx
svm
and requires:
/dev/kvm
The installer supports the AArch64 Cloud Hypervisor static release asset:
cloud-hypervisor-static-aarch64
The installer does not add a separate host-page-size check.
The installer requires Linux kernel 6.6 or newer.
The running kernel version is parsed and installation is aborted when it is below 6.6.
The installer also reports the Cloud Hypervisor upstream recommended host-kernel baseline of 5.13+, while retaining its own Debian 13 / kernel 6.6+ installation requirement.
The installer is designed to be re-run.
Each run:
- Verifies the Debian host.
- Installs missing dependencies.
- Detects the host architecture.
- Retrieves the latest stable Cloud Hypervisor release.
- Validates the release binary.
- Configures KVM permissions.
- Installs the Cloud Hypervisor binary.
- Ensures the system data directories exist.
- Tests Cloud Hypervisor execution.
The installed binary remains:
/usr/local/bin/cloud-hypervisor
The repository also includes:
cloud-hypervisor-demo-alpine.sh
The demo creates and boots a real Alpine Linux VM using Cloud Hypervisor.
The demo is intentionally small and demonstrates:
- Direct kernel boot
- Initramfs boot
- A persistent ext4 root filesystem
- Virtio block storage
- Virtio networking
- TAP networking
- IPv4 NAT through the host
- Cloud Hypervisor's API socket
- Serial-console access
- No firmware
- CPU hotplug configuration
- Memory hotplug configuration
The demo uses Alpine Linux:
Alpine 3.24.1
Architecture: x86_64
After Cloud Hypervisor has been installed:
chmod +x cloud-hypervisor-demo-alpine.sh
sudo ./cloud-hypervisor-demo-alpine.shThe script automatically re-executes itself with sudo when necessary.
The VM runs in the foreground. Its serial console is attached to the terminal, so the terminal becomes the VM console while Cloud Hypervisor is running.
The demo stores its files under:
/var/lib/cloud-hypervisor-data/test-alpine/
The important files are:
/var/lib/cloud-hypervisor-data/test-alpine/
├── alpine-100m.raw
├── vmlinuz-cloud-hypervisor
├── initramfs-cloud-hypervisor
├── linux-cloud-hypervisor/
└── ch-alpine.sock
A temporary build directory is also used while generating the kernel/initramfs and is removed after the build completes.
The VM directory is restricted to mode 0700.
The demo downloads:
alpine-minirootfs-3.24.1-x86_64.tar.gz
from the Alpine Linux CDN.
It downloads the corresponding .sha256 file and verifies the minirootfs with:
sha256sum -cThe minirootfs is then extracted into a 100 MiB ext4 disk image.
The disk image is:
/var/lib/cloud-hypervisor-data/test-alpine/alpine-100m.raw
It is created with:
100 MiB
ext4
label: alpine-root
The filesystem is configured to mount itself as:
LABEL=alpine-root / ext4 defaults 0 1
The demo no longer uses the Alpine linux-virt kernel. Instead, it builds a Linux kernel from the Cloud Hypervisor kernel configuration and uses that kernel for direct VM boot. This keeps the guest kernel configuration focused on the hardware and features required by the Cloud Hypervisor VM environment.
The Cloud Hypervisor kernel source is kept locally so subsequent builds can reuse the existing source tree and .config rather than cloning the kernel again.
The kernel build requires the host Linux build toolchain and kernel build dependencies. The resulting kernel is copied into the VM directory and used directly by Cloud Hypervisor.
The demo also generates an initramfs containing the required guest functionality, including virtio and ext4 support. This is important because the VM boots from an ext4 root filesystem using virtio storage.
The generated runtime files are:
vmlinuz-cloud-hypervisor
initramfs-cloud-hypervisor
The kernel source/build tree is retained under the VM directory for incremental rebuilds. It can be removed manually after kernel development is complete, but doing so causes the next build to clone the source again.
The demo verifies that the generated initramfs contains ext4.ko when lsinitramfs is available.
Cloud Hypervisor is started with:
CPU:
boot=1
max=4
Memory:
initial=256 MiB
hotplug=2 GiB
Disk:
persistent 100 MiB ext4 image
Network:
TAP interface
192.168.100.0/24
Serial:
tty
Console:
disabled
Firmware:
none
The kernel command line includes:
console=ttyS0,115200
modules=virtio_pci,virtio_blk,ext4
root=LABEL=alpine-root
rootfstype=ext4
rw
init=/sbin/init
This is a direct kernel boot rather than a firmware-based boot.
The demo creates:
tap0
with the host-side address:
192.168.100.1/24
The Alpine VM configures:
192.168.100.2/24
and uses:
192.168.100.1
as its default gateway.
DNS is configured inside the VM as:
1.1.1.1
8.8.8.8
The host enables IPv4 forwarding and configures an nftables NAT table named:
ch_nat
The VM's traffic is masqueraded through the host's normal outbound interface.
The demo also disables strict reverse-path filtering for the relevant interfaces and attempts to disable TAP TX checksum offload when ethtool is available.
The demo intentionally clears the Alpine root password:
root::
This is suitable for a disposable local demonstration but is not an appropriate configuration for a production VM.
Do not expose the demo VM directly to an untrusted network without replacing this configuration with proper authentication and access controls.
The demo configures BusyBox as the VM init process:
/sbin/init -> /bin/busybox
It creates a minimal /etc/inittab that:
- Remounts the root filesystem read/write
- Mounts
/proc - Mounts
/sys - Mounts
/dev - Mounts
/run - Sets the hostname
- Configures
eth0 - Starts a shell on
ttyS0 - Starts a shell on
tty1
The VM hostname is:
alpine-ch
The serial console is therefore the primary interactive console when the demo is running.
The demo creates its API socket at:
/var/lib/cloud-hypervisor-data/test-alpine/ch-alpine.sock
The socket is passed to Cloud Hypervisor with:
--api-socket
This makes the Cloud Hypervisor API available for VM management while the VM is running.
The Alpine root filesystem is persistent.
The demo does not recreate the 100 MiB disk if it already exists. On subsequent runs, it detects the existing Alpine filesystem and reuses it.
The Cloud Hypervisor kernel and initramfs are regenerated by the demo when the build step runs. The kernel source tree is retained so subsequent builds can be incremental.
The VM therefore has persistent filesystem state across demo runs, while the Cloud Hypervisor VM process itself is recreated each time.
The demo creates or recreates:
tap0
and replaces the nftables table:
ch_nat
The TAP interface and nftables configuration are host networking state, not files stored inside the VM.
If the demo is stopped, inspect the host networking state with:
ip addr show tap0
sudo nft list table ip ch_natThe demo script itself does not implement a final cleanup routine for the TAP interface or the ch_nat nftables table.
Check Cloud Hypervisor:
cloud-hypervisor --versionCheck KVM:
ls -l /dev/kvmCheck TUN/TAP:
ls -l /dev/net/tunCheck the demo TAP interface:
ip addr show tap0Check the NAT rules:
sudo nft list table ip ch_natCheck the demo directory:
sudo ls -la /var/lib/cloud-hypervisor-data/test-alpine/Both scripts use:
set -euo pipefailThe installer aborts when required host validation or installation steps fail.
Examples include:
- Unsupported Debian version
- Unsupported architecture
- Kernel below 6.6
- Missing hardware virtualization
- Missing
/dev/kvm - Inaccessible
/dev/kvm - Missing
/dev/net/tun - Missing required package
- Invalid GitHub release metadata
- Missing official release asset
- Invalid downloaded ELF binary
- Architecture mismatch
- Failed Cloud Hypervisor execution
The Alpine demo also stops on failed downloads, failed checksum verification, invalid disk creation, failed filesystem setup, failed Alpine package installation, failed initramfs generation, missing KVM, or failed network setup.
The intended project layout is:
.
├── README.md
├── install-cloud-hypervisor.sh
└── cloud-hypervisor-demo-alpine.sh
A successful installer reports information similar to:
============================================================
Cloud Hypervisor installed successfully
============================================================
Architecture : x86_64
Version : <version>
Kernel : <kernel>
KVM Status : verified (read/write access configured)
TUN/TAP : verified
Binary : /usr/local/bin/cloud-hypervisor
Data Directory : /var/lib/cloud-hypervisor-data
Base Images : /var/lib/cloud-hypervisor-data/base
Instances : /var/lib/cloud-hypervisor-data/instances
Snapshots : /var/lib/cloud-hypervisor-data/snapshots
This installer is separate from the Cloud Hypervisor project.
Cloud Hypervisor is an independent open-source project. Refer to the upstream project for its licensing terms.
The source code for this project is licensed under the GNU General Public License v3.0 (GPLv3). See the LICENSE file for the full license terms.
If you fork or build upon this project, attribution to the original project is appreciated.