Cocoon boots two image families: OCI VM images (kernel + rootfs layers, direct boot) and cloud images (qcow2, UEFI boot). A registry image without vmlinuz and initrd.img is rejected after download, so ordinary container images cannot be booted.
On arm64, Cloud Hypervisor gives a guest ACPI only through firmware, so cocoon starts an OCI image with --firmware CLOUDHV.fd next to --kernel, --initramfs and --cmdline, plus --fw-cfg-config kernel=on,cmdline=on,initramfs=on,acpi_table=on. EDK2 receives the kernel over fw_cfg and starts it through its EFI stub, so PCI hot-plug (vm net NIC resize, device detach) and the rtc-efi clock work. This needs the EDK2 firmware and a Cloud Hypervisor built with fw_cfg, both installed by cocoon-check --upgrade; vm create and vm run fail with firmware not found when the firmware is missing. VMs and snapshots created by an older cocoon keep their kernel-only boot. The Firecracker backend still boots the kernel directly.
# OCI VM image from a registry
cocoon image pull ghcr.io/cocoonstack/cocoon/ubuntu:24.04
# Cloud image from an HTTP(S) URL (auto-converted to qcow2 v3)
cocoon image pull https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img
# --force re-downloads a URL whose content was replaced upstream (OCI tags are re-resolved on every pull)
cocoon image pull --force https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img
Blobs are content-addressed (SHA-256) and deduplicated; OCI layers are converted to EROFS, cloud images to qcow2 v3. A cloud-image URL must serve an uncompressed disk image — gzip/xz/bzip2/zstd payloads are refused (cloudimg does not auto-decompress); decompress first and use image import, which does unwrap gzip. Cloud-image URL downloads are capped at 20 GiB; OCI pulls and image import are uncapped.
cocoon image import NAME [FILE...] imports local files or stdin, auto-detected by magic bytes (gzip-wrapped input supported):
QFI magic) → stored as a cloud imagecocoon image import myimg disk.qcow2
cat layers.tar.gz | cocoon image import mylayers
Import preserves the input files. A cached cloud-image import reuses the blob without copying the input; if GC collects that blob before publication, import falls back to a private temporary copy.
cocoon image list
cocoon image inspect ghcr.io/cocoonstack/cocoon/ubuntu:24.04
cocoon image rm sha256:abc123def456
image rm drops the reference only; run cocoon gc to reclaim the blobs (see GC). A digest prefix must be at least 12 hex characters and unambiguous: a shorter prefix matches nothing, and both image rm and image inspect treat a prefix that matches more than one image as not-found — use a longer prefix.
Pre-built OCI VM images are published to GHCR and auto-built by GitHub Actions when os-image/ changes. Three families ship: Ubuntu (22.04, 24.04, plus the 24.04-chrome / 24.04-xface / 24.04-picoclaw variants), Debian (13), and Android (14.0, 15.0, 15.0-gms, 16.0-gms-h264). OS Images lists every tag.
cocoon image pull ghcr.io/cocoonstack/cocoon/ubuntu:24.04
cocoon image pull ghcr.io/cocoonstack/cocoon/debian:13
cocoon image pull ghcr.io/cocoonstack/cocoon/android:15.0
Every image carries a kernel and initramfs; the Ubuntu and Debian images add a systemd-based rootfs with an overlayfs boot script, while the Android 14.0, 15.0 and 15.0-gms images boot Android init directly. Every official OS image (Ubuntu, Debian, Android) bakes cocoon-agent (vsock exec) with auto-start; the Ubuntu and Debian images, including the Ubuntu-based android:16.0-gms-h264, additionally enable sshd with PermitRootLogin yes so ssh root@<vm> works out of the box (default root:cocoon).
Build scripts, image contents, and the local start.sh harness are documented in OS Images.