{"id":38805774,"url":"https://github.com/spin-stack/spinbox","last_synced_at":"2026-01-17T12:50:26.255Z","repository":{"id":331467748,"uuid":"1122936154","full_name":"spin-stack/spinbox","owner":"spin-stack","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-10T01:00:47.000Z","size":4621,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-10T22:09:26.650Z","etag":null,"topics":["containerd","erofs","qemu","shim"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spin-stack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-25T21:28:30.000Z","updated_at":"2026-01-10T14:13:56.000Z","dependencies_parsed_at":"2026-01-10T23:05:04.230Z","dependency_job_id":null,"html_url":"https://github.com/spin-stack/spinbox","commit_stats":null,"previous_names":["aledbf/qemubox","spin-stack/spinbox"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/spin-stack/spinbox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spin-stack%2Fspinbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spin-stack%2Fspinbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spin-stack%2Fspinbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spin-stack%2Fspinbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spin-stack","download_url":"https://codeload.github.com/spin-stack/spinbox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spin-stack%2Fspinbox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28508636,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T11:50:55.898Z","status":"ssl_error","status_checked_at":"2026-01-17T11:50:55.569Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["containerd","erofs","qemu","shim"],"created_at":"2026-01-17T12:50:25.569Z","updated_at":"2026-01-17T12:50:26.244Z","avatar_url":"https://github.com/spin-stack.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# spinbox\n\n**Lightweight VM isolation for containers**\n\n[![CI](https://github.com/spin-stack/spinbox/actions/workflows/ci.yml/badge.svg)](https://github.com/spin-stack/spinbox/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/spin-stack/spinbox/branch/main/graph/badge.svg)](https://codecov.io/gh/spin-stack/spinbox)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)\n\n*Run each container in its own lightweight QEMU/KVM virtual machine*\n\n[Quick Start](#quick-start) • [Demos](#demos) • [Architecture](#architecture) • [Documentation](#documentation)\n\n\u003c/div\u003e\n\n---\n\n\u003e **TL;DR**: Experimental containerd runtime providing VM-level isolation with ~300ms boot times.\n\u003e Get the security of VMs with the UX of containers.\n\n## Features\n\n- ✅ **Strong isolation** — One VM per container via KVM hardware virtualization\n- ✅ **Fast boot** — ~300ms with optimized kernel and systemd\n- ✅ **Standard networking** — CNI plugin compatible (Calico, Cilium, etc.)\n- ✅ **Efficient storage** — EROFS snapshots with inline compression\n- ✅ **Snapshot \u0026 commit** — Persist VM state like Docker images\n- ✅ **containerd native** — Works with existing tooling (ctr, nerdctl, crictl)\n\n## Table of Contents\n\n- [Demos](#demos)\n- [Design Choices](#design-choices)\n- [Quick Start](#quick-start)\n- [Architecture](#architecture)\n- [Security](#security)\n- [Comparison](#comparison)\n- [Development](#development)\n- [Roadmap](#roadmap)\n\n## Demos\n\n### Boot \u0026 Docker-in-VM\n[![asciicast](https://asciinema.org/a/5GJ0fPswxolRL4kiUQTpry6au.svg)](https://asciinema.org/a/5GJ0fPswxolRL4kiUQTpry6au)\n\nLaunch a full Ubuntu VM with Docker pre-installed. Shows ~300ms boot time with systemd, running containers inside the isolated VM - nested virtualization without the overhead.\n\n### Snapshot \u0026 Commit\n[![asciicast](https://asciinema.org/a/aIk4RocQFPk7I0QizhRwULKLz.svg)](https://asciinema.org/a/aIk4RocQFPk7I0QizhRwULKLz)\n\nPersist disk state between VM runs: install packages, create files, then commit to a new image with `nerdctl commit`. The next VM boots with all changes preserved - like Docker commits, but for entire VMs.\n\n\u003e **Note**: Snapshot support (for EROFS) requires a custom containerd build from [aledbf/containerd@aledbf/erofs-snapshot-narrow](https://github.com/aledbf/containerd/tree/aledbf/erofs-snapshot-narrow) until the changes are upstreamed.\n\n---\n\n## Design Choices\n\nspinbox is inspired by [nerdbox](https://github.com/containerd/nerdbox), which pioneered the \"shim-level VM isolation\" approach for containerd using [libkrun](https://github.com/containers/libkrun).\n\n**spinbox** takes a different path, optimized for Linux server workloads:\n\n| | nerdbox | spinbox |\n|---|---------|---------|\n| **VMM** | libkrun (Rust) | QEMU/KVM |\n| **Platforms** | Linux, macOS, Windows | Linux only |\n| **Focus** | Cross-platform, rootless | Server workloads, KVM features |\n| **Networking** | libkrun networking | Standard CNI plugins |\n\n**Why QEMU/KVM?**\n\n1. **QEMU's maturity** - Battle-tested VMM with extensive device support, debugging tools (QMP, gdbstub), and broad kernel compatibility\n2. **Standard CNI networking** - Reuse existing CNI plugins (Calico, Cilium, etc.) instead of custom networking\n3. **KVM-specific features** - CPU/memory hotplug, vhost-net, virtio-blk, and other Linux-specific optimizations\n4. **Simpler deployment** - Single static binary VMM without Rust runtime dependencies\n\nIf you need cross-platform support or rootless containers, check out [nerdbox](https://github.com/containerd/nerdbox).\n\n## Why VMs?\n\nVM isolation provides a stronger security boundary than namespace-based containers, while maintaining compatibility with standard containerd tooling.\n\n## Quick Start\n\n### Prerequisites\n\n- Linux with KVM (`/dev/kvm` accessible)\n\n### Install\n\nDownload the latest release and run the installer:\n\n```bash\ntar xzf spinbox-VERSION-linux-x86_64.tar.gz\ncd spinbox-VERSION-linux-x86_64\nsudo ./install.sh\n```\n\nThe release includes everything: containerd, QEMU, kernel, CNI plugins, and configuration.\n\nFor systems with existing containerd, use shim-only mode:\n\n```bash\nsudo ./install.sh --shim-only\n```\n\nSee `./install.sh --help` for all options.\n\n### Start\n\n```bash\nsudo systemctl enable --now spinbox\nsudo systemctl start --now spinbox\n```\n\n### Run a Container\n\n```bash\n# Add spinbox binaries to PATH\nexport PATH=/usr/share/spin-stack/bin:$PATH\n\n# Pull an image\nctr --address /var/run/spin-stack/containerd.sock image pull \\\n  --snapshotter spin-erofs ghcr.io/spin-stack/spinbox/sandbox:v0.0.11\n\n# Run with spinbox runtime\nctr --address /var/run/spin-stack/containerd.sock run -t --rm \\\n  --snapshotter spin-erofs \\\n  --runtime io.containerd.spinbox.v1 \\\n  ghcr.io/spin-stack/spinbox/sandbox:v0.0.11 test-qemu-shim\n```\n(use root:spinbox to log in)\n\n## Architecture\n\n**Key components:**\n- **Shim**: Manages VM lifecycle and proxies I/O via vsock\n- **CNI**: Standard CNI plugin chains for networking\n- **QEMU**: Boots lightweight VMs with virtio devices\n- **vminitd**: Init daemon inside VM that runs crun\n\n\u003cdetails\u003e\n\u003csummary\u003e📐 View Architecture Diagram\u003c/summary\u003e\n\n```mermaid\ngraph LR\n    %% Host (Linux)\n    subgraph host [\"**Host (Linux)**\"]\n        direction TB\n        containerd:::hostproc\n        shim[containerd-shim-spinbox-v1]:::hostproc\n        cni[CNI Plugins\u003cbr/\u003ebridge, firewall, IPAM]:::netdev\n        tap[TAP device]:::netdev\n        store[EROFS snapshots]:::block\n        kernel[VM kernel]:::hostvm\n        initrd[VM initrd]:::hostvm\n        qemu[QEMU/KVM]:::hypervisor\n\n        containerd -- \"shim v2 ttrpc\" --\u003e shim\n        shim -- \"CNI setup\n        (netns/tap/IPAM)\" --\u003e cni\n        cni -- \"create/attach\" --\u003e tap\n        shim -- \"spawn/config\n        (kernel args, vsock CID)\" --\u003e qemu\n        store -- \"rootfs via\n        virtio-blk\" --\u003e qemu\n        kernel -- \"bzImage\" --\u003e qemu\n        initrd -- \"initrd\" --\u003e qemu\n        qemu -.-\u003e|virtio-net to TAP| tap\n    end\n\n    %% Linux VM\n    subgraph vm [\"**Linux VM**\"]\n        direction TB\n        vminitd[vminitd\u003cbr/\u003ePID 1 / TTRPC]:::vmcore\n        systemsvc[system service]:::srv\n        bundlesvc[bundle service]:::srv\n        crun[crun\u003cbr/\u003eOCI Runtime]:::runtime\n        container[Container Process]:::ctr\n\n        vminitd --\u003e systemsvc\n        vminitd --\u003e bundlesvc\n        vminitd --\u003e crun\n        crun --\u003e container\n    end\n\n    %% Connections between host and VM\n    shim -.-\u003e|vsock ttrpc + stdio| vminitd\n\n    %% Styling with classDefs for consistency and clarity\n    classDef hostproc fill:#2962ff,stroke:#152f6b,stroke-width:2px,color:#fff\n    classDef netdev fill:#26a69a,stroke:#00695c,stroke-width:2px,color:#fff\n    classDef block fill:#ffee58,stroke:#666600,stroke-width:2px,color:#111\n    classDef hostvm fill:#ec407a,stroke:#880e4f,stroke-width:2px,color:#fff\n    classDef hypervisor fill:#6d4c41,stroke:#442b2d,stroke-width:2px,color:#fff\n    classDef vmcore fill:#8e24aa,stroke:#4a148c,stroke-width:2px,color:#fff\n    classDef srv fill:#80cbc4,stroke:#004d40,stroke-width:2px,color:#111\n    classDef runtime fill:#ffb300,stroke:#6d4c00,stroke-width:2px,color:#111\n    classDef ctr fill:#ef5350,stroke:#b71c1c,stroke-width:2px,color:#fff\n\n    class containerd,shim hostproc\n    class cni,tap netdev\n    class store block\n    class kernel,initrd hostvm\n    class qemu hypervisor\n    class vminitd vmcore\n    class systemsvc,bundlesvc srv\n    class crun runtime\n    class container ctr\n\n    linkStyle 9 stroke-dasharray:4 4,stroke-width:2px,stroke:#6d4c41\n    linkStyle 8 stroke-width:2px,stroke:#00acc1,stroke-dasharray:3 6\n```\n\n\u003c/details\u003e\n\n## How It Works\n\n1. **containerd** calls the spinbox shim to create a container\n2. **CNI** allocates an IP and creates a TAP device\n3. **QEMU** boots a microVM with kernel, network, and storage\n4. **vminitd** (PID 1 in VM) connects to shim via vsock\n5. **crun** starts the container process with resource limits\n6. Container I/O flows through vsock to containerd\n\n\u003cdetails\u003e\n\u003csummary\u003e📊 View Container Lifecycle Sequence Diagram\u003c/summary\u003e\n\n```mermaid\nsequenceDiagram\n    autonumber\n\n    %% Group host-side actors in a blue box\n    box Host (Linux)\n        participant C as containerd\n        participant S as containerd-shim\n        participant N as CNI Plugins\n        participant Q as QEMU/KVM\n    end\n\n    %% Group VM-side actors in a green box\n    box VM (Guest Linux)\n        participant V as vminitd (PID 1)\n        participant R as crun\n    end\n\n    %% --- Create Phase ---\n    rect rgb(220,240,255)\n    note over C,R: Create Phase\n    activate C\n    C-\u003e\u003e+S: CreateTask(bundle, rootfs)\n    activate S\n    S-\u003e\u003eS: Check KVM\u003cbr/\u003eLoad OCI spec\u003cbr/\u003ePrepare VM\n    S-\u003e\u003eS: Setup EROFS mounts\n    S-\u003e\u003eN: Setup network (CNI)\n    N--\u003e\u003eS: Return TAP device + IP config\n    S-\u003e\u003eQ: Start VM\u003cbr/\u003e(kernel, initrd, virtio-devs)\n    deactivate S\n    activate Q\n    Q--\u003e\u003eV: Boot kernel\u003cbr/\u003estart vminitd (PID 1)\n    deactivate Q\n    activate V\n    V--\u003e\u003eS: Connect via vsock\n    S-\u003e\u003eV: Send bundle (OCI, rootfs)\n    S-\u003e\u003eV: CreateTask\n    V-\u003e\u003eR: OCI create container\n    activate R\n    R--\u003e\u003eV: Container created\n    deactivate R\n    V--\u003e\u003eS: Return PID\n    S--\u003e\u003eC: Return PID\n    deactivate C\n    deactivate S\n    deactivate V\n    end\n    \n    %% --- Start Phase ---\n    rect rgb(224,255,224)\n    note over C,R: Start Phase\n    activate C\n    C-\u003e\u003eS: Start\n    activate S\n    S-\u003e\u003eV: Start\n    activate V\n    V-\u003e\u003eR: Start container\n    activate R\n    R--\u003e\u003eV: Running\n    deactivate R\n    V--\u003e\u003eS: PID\n    S--\u003e\u003eC: PID\n    deactivate C\n    deactivate S\n    deactivate V\n    end\n\n    %% --- Delete Phase ---\n    rect rgb(255,228,216)\n    note over C,R: Delete Phase\n    activate C\n    C-\u003e\u003eS: Delete\n    activate S\n    S-\u003e\u003eV: Delete\n    activate V\n    V-\u003e\u003eR: Delete container\n    activate R\n    R--\u003e\u003eV: Deleted\n    deactivate R\n    V--\u003e\u003eS: Exit status\n    deactivate V\n    S-\u003e\u003eS: Stop hotplug controllers\n    S-\u003e\u003eQ: Shutdown VM\n    activate Q\n    Q--\u003e\u003eS: VM exited\n    deactivate Q\n    S-\u003e\u003eN: Release network\n    N--\u003e\u003eS: Network cleaned\n    S--\u003e\u003eC: Exit status\n    deactivate C\n    deactivate S\n    end\n```\n\n\u003c/details\u003e\n\n## Security\n\nMultiple isolation layers:\n\n- **VM boundary**: Hardware virtualization (KVM) isolates each container\n- **Network**: Isolated TAP devices, firewall rules via CNI\n- **Storage**: Read-only EROFS via virtio-blk\n- **Resource**: cgroups v2 prevents resource exhaustion\n- **Communication**: vsock (no network-based IPC)\n\n## Limitations\n\n- Linux only (KVM required)\n- x86_64 only (arm64 untested)\n- One VM per container (no sharing)\n- Cold start for each container (no VM pooling)\n\n## Development\n\n### Build from Source\n\n```bash\n# Install Task runner\ngo install github.com/go-task/task/v3/cmd/task@latest\n\n# Build everything (requires Docker for kernel/initrd)\ntask build\n\n# Create release tarball\ntask release\n```\n\n### Repository Layout\n\n```\ncmd/           - Entrypoints (shim, vminitd)\ninternal/      - Implementation\n  host/        - VM, network, storage management\n  shim/        - Containerd shim implementation\n  guest/       - vminitd and guest services\n  config/      - Configuration management\napi/           - Protobuf/TTRPC definitions\nbuild/         - Build inputs (kernel config)\ndeploy/        - Installation scripts and configs\nexamples/      - Example configurations\nhack/          - Development scripts\nimages/        - Container/VM image builds\n```\n\n## Comparison\n\n| Project | Approach | Trade-offs |\n|---------|----------|------------|\n| **spinbox** | VM per container (QEMU/KVM) | Strong isolation, Linux-only, cold start overhead |\n| **[nerdbox](https://github.com/containerd/nerdbox)** | VM per container (libkrun) | Cross-platform, rootless, newer VMM |\n| **[Kata Containers](https://katacontainers.io/)** | VM per container (multiple VMMs) | Production-ready, more complex |\n| **[gVisor](https://gvisor.dev/)** | User-space kernel | No VM overhead, different syscall compatibility |\n| **runc** | Namespaces only | Fast, weaker isolation |\n\n## Roadmap\n\n- **Remove KVM requirement**: Support [PVM (Protected Virtual Machine)](https://github.com/virt-pvm/linux) kernel for environments without `/dev/kvm` ([LWN article](https://lwn.net/Articles/963718/))\n- ~~**Filesystem merge snapshots**: Leverage containerd's [fsmerge feature](https://github.com/containerd/containerd/pull/12374) for more efficient storage~~\n- **Metrics and tracing**: Add TTRPC tracing to provide detailed observability into VM and container behavior\n- **Annotations for features**: Allow enabling/disabling features (CPU/memory hotplug, etc.) via OCI annotations\n- ~~**Snapshot demo**: Demonstrate VM snapshots - restart a VM with previous state/changes preserved~~ ✓ [Done](https://asciinema.org/a/aIk4RocQFPk7I0QizhRwULKLz)\n\n## License\n\nApache 2.0\n\n## Contributing\n\nExperimental project. Issues and PRs welcome.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspin-stack%2Fspinbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspin-stack%2Fspinbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspin-stack%2Fspinbox/lists"}