Firecracker Dockerfile: Building Container Images for MicroVMs
Learn how to build Firecracker rootfs images using Dockerfile workflows. Convert containers to microVMs for AI agents, sandboxes, and untrusted code.
DM
Docker made packaging trivial. Firecracker makes isolation bulletproof. But they don't speak the same language: a Dockerfile produces an OCI image, while Firecracker needs a rootfs. The gap between "docker build" and "firecracker boot" — between a Firecracker Dockerfile and a running microVM — is where most developers get stuck.
When you try to boot a Docker image in Firecracker, nothing happens. The two tools solve different problems. You need a bridge.
This guide walks you through why standard Docker workflows fail with Firecracker, how teams convert container images to rootfs, and which tools automate the work so you don't script it yourself.
TL;DR:
- A Dockerfile builds OCI images for containers; Firecracker needs a rootfs (filesystem only, no container metadata).
- Tools like buildfs, land, and firecracker-containerd let you reuse Dockerfile-like syntax to create Firecracker rootfs images automatically.
- The container to microvm workflow pairs a Docker image build step with a rootfs extraction or compilation step, then boots the result in Firecracker.
- For untrusted code (AI agents, CI runners, sandboxes), Firecracker's isolated kernel is worth the tooling complexity. For trusted workloads, Docker stays simpler.
What Is a Firecracker Dockerfile?
There's no such thing as a "Firecracker Dockerfile" in the strict sense. Firecracker doesn't natively understand Dockerfile syntax. What exists instead is a category of tools that let you write Dockerfile-like build specifications and produce a Firecracker-compatible rootfs instead of an OCI container image.
A traditional Dockerfile outputs a layered image: metadata, a root filesystem, and instructions for the container runtime. When you run docker run, the runtime unpacks those layers, reads the entrypoint, and executes the process inside a namespace that shares the host kernel.
Firecracker works differently. A Firecracker microVM needs a Linux kernel image and a flat root filesystem. There's no "container runtime" in the middle. Firecracker boots the kernel directly, mounts the rootfs, and runs your application as if it's a full operating system. The Firecracker Dockerfile approach automates turning a Docker image (or a Dockerfile) into that rootfs.
Tools like buildfs (a Rust CLI that consumes a TOML build script) let you declare your rootfs the same way you'd declare a Firecracker Dockerfile, with a base image, package installations, and overlay files. buildfs handles the plumbing: it pulls the container image, runs your build steps inside a temporary container, extracts the filesystem, and outputs a rootfs tarball ready for Firecracker.
Why Docker Workflows Don't Directly Work with Firecracker
A Docker image is not a rootfs. This is the first friction point.
Docker layers stack on top of a base image, and the same mechanics apply when you translate a Firecracker Dockerfile. Each instruction creates a new layer: RUN commands add files, COPY copies artifacts, ENV sets variables. When you run a container, Docker unzips these layers into a union filesystem. The container runtime (containerd, CRI-O, or Docker's daemon) then sets up namespaces, cgroups, and seccomp rules around it.
Firecracker has no concept of Docker's metadata, union filesystems, or runtime configuration. When you hand it a rootfs, it mounts it as a regular filesystem inside the guest kernel. There's no layer unpacking, no reading of CMD or ENTRYPOINT instructions from image metadata.
This means you can't just point Firecracker at a Docker image and boot. You need to extract the filesystem layers into a flat rootfs, figure out how to start your application (often by writing an init script or systemd unit), and ensure the kernel image and rootfs are compatible.
Additionally, Firecracker's minimal device model is a feature, not a limitation. It exposes fewer devices to the guest than a traditional hypervisor, which means faster boot and a smaller attack surface. But it also means certain workloads, those needing exotic hardware passthrough or complex device configurations, won't run without workarounds.
For most web services, backends, and sandboxed code execution, this is fine. For legacy applications expecting a full hardware model, it's a blocker.
How to Convert Docker Images to Firecracker Rootfs
Several approaches exist, ranging from manual to fully automated.
The manual approach: Pull a Docker image, export its filesystem layers, create an init script, compile a kernel, and package it all. This teaches you the architecture but is error-prone and not repeatable. Most teams abandon it after the first try.
buildfs, a Rust tool published on crates.io, automates this. You write a TOML file — effectively a Firecracker Dockerfile — declaring a base image, packages to install, scripts to run, and overlay files to inject. Run buildfs build, and it connects to your container engine (Docker or Podman), pulls the image, executes your build steps inside a temporary container, extracts the filesystem, and outputs a rootfs tarball. The tool validates your build script for declarativity before running anything, catching missing files or broken references early.
firecracker-containerd, a containerd plugin, lets containerd itself manage the rootfs build and Firecracker microVM lifecycle. You declare a microVM the same way you'd declare a pod, and containerd orchestrates the extraction and boot. This integrates well if you already run containerd, but it adds a control plane dependency.
land, a GitHub tool, takes a Docker image as input and converts it directly to a Firecracker VM image. It abstracts away the rootfs extraction step, letting you reuse existing Docker images without rewriting build logic.
The common pattern: base your rootfs on a minimal Linux distro (Alpine, Debian slim, or Fedora minimal), add your application and dependencies, strip out what Firecracker won't use, and test the boot on real hardware or a box with KVM enabled.
Container to MicroVM Workflow: Tools and Approaches
Most production setups don't build Firecracker images by hand. Instead, they automate a pipeline:
- Write a Dockerfile for your application (or reuse an existing one).
- Use a tool to convert that Docker image to a Firecracker rootfs (buildfs, land, or firecracker-containerd).
- Boot the rootfs inside a Firecracker microVM for testing.
- Archive the rootfs and kernel as an immutable snapshot.
- Deploy that snapshot by booting new microVMs from it, on demand.
This docker image microVM workflow feels natural to teams already using containers. You keep the Dockerfile syntax you know; the tooling handles the conversion. When you need to update the rootfs, rebuild the Docker image, re-run the conversion, and redeploy.
For AI-agent sandboxes, ephemeral CI runners, and untrusted code execution, this pattern is powerful. Each microVM gets a fresh copy of the rootfs and its own kernel instance. If the code crashes, corrupts memory, or escapes confinement, it affects only that microVM. Other instances remain unaffected because they don't share a kernel.
Teams running multi-tenant platforms (like online code editors or serverless providers) often pair this with a control plane that orchestrates microVM creation, networking, and cleanup. Firecracker exposes a REST API for each running microVM, so your orchestrator can configure vCPUs, memory, network interfaces, and block devices programmatically.
Some teams also nest Docker inside Firecracker. Boot a Firecracker microVM as the isolation boundary, then run Docker containers built from a normal Firecracker Dockerfile inside that microVM for application packaging. This gives you the developer convenience of containers with the hardware isolation of a VM, useful when you trust your application layer but need a strong boundary against the host.
Common Mistakes When Building Firecracker Images
Expecting the Dockerfile to work unchanged. Dockerfiles often include multi-stage builds, health checks, and runtime metadata (EXPOSE, HEALTHCHECK) that don't translate to Firecracker rootfs builds. When converting, strip out container-specific directives and focus on the files and binaries you actually need.
Not testing the kernel and rootfs combination. Firecracker requires a Linux kernel image (a vmlinux file, often compiled from a 5.10+ kernel). If your rootfs was built on Debian and your kernel is too old or missing drivers, boot will fail silently — and no Firecracker Dockerfile can patch that over, since it only describes userspace. Always test locally on bare metal or a cloud instance with nested virtualization enabled.
Ignoring the rootfs size. Docker layers compress well; Firecracker rootfs images don't. Omit debug symbols, documentation, and unused packages. A minimal nginx rootfs should be well under 100 MB. A bloated one wastes memory and slows boot. Use a tool like du to profile the final image.
Forgetting the init process. Firecracker boots a kernel and mounts a rootfs, but it doesn't run a container runtime. You need an init system (systemd, runit, or a simple init script) to start your application. Without it, the kernel boots but nothing runs.
Not handling signals properly. In a Docker container, a SIGTERM tells your application to shut down gracefully. In a Firecracker microVM, if the init process doesn't propagate signals correctly, your application might hang on shutdown. Test graceful termination before production.
FAQ
Can I Convert an Existing Docker Image to Firecracker Without Rewriting It?
Yes. Tools like land and buildfs let you take any Docker image and extract it to a Firecracker rootfs. However, you'll usually need to add an init script or systemd unit to start your application, since Docker's ENTRYPOINT/CMD metadata doesn't carry over.
Do I Need to Modify My Dockerfile to Use Firecracker Dockerfile Tools?
Not necessarily. Most tools accept a standard Dockerfile or Docker image as input. If your Dockerfile is already minimal and doesn't rely on container runtime features (like health checks), it often works as-is. Complex multi-stage Dockerfiles may need simplification.
What's the Difference Between Running Docker Inside Firecracker vs. Running Firecracker Directly?
Docker inside Firecracker adds a container layer on top of the VM boundary. This is useful if you want orchestration, layering, and runtime flexibility, but it uses more memory. Running Firecracker directly is faster and leaner for simple, single-application workloads.
Is Firecracker Suitable for AI Agent Sandboxes?
Yes. AI agents executing generated code need strict isolation. Firecracker provides a separate kernel instance and hardware boundary per microVM, so one agent's crash or escape attempt cannot reach another — even when each sandbox image starts life as a Firecracker Dockerfile. Container-based sandboxes share the host kernel, which is a risk. Firecracker and gVisor are the standard choices for this use case in 2026.
From Dockerfile to Firecracker microVM
Convert your container image into a Firecracker rootfs and boot it on Krova in seconds, without managing a Kubernetes cluster.




