A micro-VMM in pure Go that does everything Firecracker does at the KVM level — virtio devices, jailer, seccomp — and adds the developer experience on top. Pull any OCI image, build any Dockerfile, clone any git repo, orchestrate Compose stacks. Each service becomes a real Linux VM.

$ sudo ./gocracker run --image alpine:latest --kernel ./vmlinux --wait
[oci] cache hit alpine:latest (linux/amd64)
[container:INFO] started id=gc-26655 duration=284ms
[vmm:INFO] vm running id=gc-26655 vcpus=1 mem_mb=128

── install ───────────────────────────────────────────

# linux/amd64 — arm64 also published, just swap the arch
curl -L https://github.com/misaelzapata/gocracker/releases/download/v0.1.0/gocracker-v0.1.0-linux-amd64.tar.gz | tar xz
cd gocracker-v0.1.0-linux-amd64

# grab a guest kernel (or build your own with `make kernel-guest`)
curl -L -o vmlinux.gz https://github.com/misaelzapata/gocracker/raw/main/artifacts/kernels/gocracker-guest-standard-vmlinux.gz
gunzip vmlinux.gz

# boot
sudo ./gocracker run --image alpine:latest --kernel ./vmlinux \
                    --cmd "echo hello from a real VM" --wait

no docker daemon · no containerd · no runc · just kvm


── features ──────────────────────────────────────────

container sources
OCI registries, local Dockerfiles (BuildKit AST), git repos with auto-detected Dockerfiles, plain directories.
compose orchestration
Docker Compose stacks as microVMs. In-guest healthchecks. depends_on with service_healthy + service_completed_successfully.
networking
--net auto creates TAP + IPv4 + NAT in one shot. Per-stack network namespaces. Deterministic per-VM MACs. Port publishing.
kvm isolation
Hardware virt + Firecracker-style jailer + per-arch seccomp + private mount namespaces + pivot_root for builds.
snapshot · restore · clone
Full RAM + vCPU + device snapshot. In-place /clone spawns a new VM with a fresh tap and re-IP'd guest. Live migration (stop-and-copy).
sandbox control plane
gocracker-sandboxd — warm pools, content-addressed templates, HMAC-signed preview URLs. Python · Go · JS SDKs.

── numbers ───────────────────────────────────────────

Ryzen AI 9 HX 370 · Linux 6.17 · /dev/kvm. Reproduce: sandboxes/examples

cold boot       alpine, warm OCI cache           ~ 80 ms
warm restore    snapshot, in-place               ~ 40 ms
lease p95       warm pool, sandboxd              ~ 1.5 ms
template hit    content-addressed cache          ~ 80 µs
regression      real-world projects in the gate    378
arch parity     x86-64 + ARM64 (Graviton 1)        full

── sdk ───────────────────────────────────────────────

Most users skip raw HTTP. Typed errors, context-manager lifecycle, pipelined CONNECT.

from gocracker_sandboxes import Sandboxd

sb = Sandboxd("http://127.0.0.1:9091")
with sb.create(image="alpine:3.20", network_mode="auto") as s:
    out = s.run_command("sh", "-lc", "wget -qO- https://example.com | head -1")
    print(out.stdout)

python · go · js / node


── why ───────────────────────────────────────────────

I fell in love with Firecracker — booting a real Linux VM in milliseconds with minimal overhead is brilliant. But every time I wanted to just run a container image as a microVM, I had to pull the image manually, extract the rootfs, build an ext4 disk, generate an initrd, write a JSON config, set up a TAP interface, configure iptables… and only then call the Firecracker API. I kept thinking: why can't I just type one command?

So I built gocracker. Hobby project that grew into something that boots 378 real-world projects, runs Flask + PostgreSQL compose stacks on ARM64 bare metal, and ships a Firecracker-compatible REST API. All in a single static binary.