Guest image (kernel + rootfs)
The manager boots Firecracker microVMs from a kernel (vmlinux) plus a root filesystem (rootfs.ext4).
Build a guest image (Debian)
From the repo root:
./scripts/build-guest-image.sh
Outputs:
services/guest-image/dist/vmlinuxservices/guest-image/dist/rootfs.ext4
There is also a convenience builder that produces both Debian + Alpine artifacts under ./dist/images/*:
make guest-images
What a guest image must have to work
At minimum, a compatible image must provide:
1) A working /sbin/init (PID 1)
This project uses a tiny C init (services/guest-image/init/guest-init.c) compiled into the rootfs as /sbin/init.
It is responsible for:
- mounting
/proc,/sys,/dev - bringing up loopback (
lo) so127.0.0.1works - starting the guest agent
- starting a vsock -> TCP bridge via
socat
2) Guest agent reachable on vsock port 8080
The manager speaks HTTP over vsock. In the default image:
- guest agent listens on TCP
127.0.0.1:8080 socat VSOCK-LISTEN:8080,fork TCP:127.0.0.1:8080bridges vsock to the agent
Guest agent endpoints include:
POST /execPOST /run-tsPOST /files/upload(tar.gz)GET /files/download(tar.gz)POST /firewall/allowlist
3) User isolation model: uid/gid 1000 and /workspace
The guest image creates a user user with uid/gid 1000 and a writable workspace mapped at /workspace (backed by /home/user on disk).
Important behavior:
execruns chrooted and treats/workspaceas the only supported filesystem root for user operations- file upload/download is restricted to
/workspaceand uses tar.gz streams - symlinks and traversal are rejected
4) Toolchain inside the jail (BusyBox + staged tools)
Because exec runs inside a minimal chroot jail, a small toolchain is available there (BusyBox plus staged binaries like git, node, npm, tar, and deno).
5) Deno for run-ts
run-ts uses Deno and executes with restricted permissions:
--allow-read=/workspace(plus minimal/etc/*reads needed for DNS + TLS)--allow-write=/workspace- optional
--allow-netif requested (and still subject to firewall allowlist) - env vars: when the API request includes
env: ["KEY=value", ...],run-tswill allow access to only those keys (soDeno.env.get("KEY")works) - structured return: scripts can call
result.set(value)/result.error(err)and the manager will includeresult/errorfields in the response JSON
Uploading images to the manager
You can either:
- set
KERNEL_PATH+BASE_ROOTFS_PATH(for “built-in” base images inside the manager container), or - upload images via the Images API/UI (artifacts stored under
IMAGES_DIR)