#micro-vm #sdk #client #api-sdk #run-time #jailer

firecracker

Rust client SDK for the Firecracker microVM API

4 releases

Uses new Rust 2024

new 0.2.3 Mar 5, 2026
0.2.1 Feb 16, 2026
0.2.0 Feb 13, 2026
0.1.0 Feb 2, 2026

#2045 in Development tools


Used in fc-cli

MIT/Apache

120KB
2K SLoC

Firecracker Rust Client SDK

Rust SDK for the Firecracker microVM API.

Crates

Crate Description
firecracker Facade — re-exports api + sdk + optional runtime
fc-api Low-level typed client, generated from Swagger spec via progenitor
fc-sdk High-level typestate wrapper: VmBuilderVm lifecycle, process management
fc-cli CLI for runtime helpers and microVM process launch

Quick Start

use firecracker::sdk::{VmBuilder, types::*};

let vm = VmBuilder::new("/tmp/firecracker.socket")
    .boot_source(BootSource {
        kernel_image_path: "/path/to/vmlinux".into(),
        boot_args: Some("console=ttyS0".into()),
        initrd_path: None,
    })
    .machine_config(MachineConfiguration {
        vcpu_count: std::num::NonZeroU64::new(2).unwrap(),
        mem_size_mib: 256,
        smt: false,
        track_dirty_pages: false,
        cpu_template: None,
        huge_pages: None,
    })
    .start()
    .await?;

vm.pause().await?;
vm.resume().await?;
vm.create_snapshot("/tmp/snap", "/tmp/mem").await?;

For operations not covered by the SDK, use the generated API client directly:

let client = vm.client();
client.describe_instance().send().await?;

Process Management

fc-sdk can spawn and manage the Firecracker process for you.

Direct (no jailer)

use firecracker::sdk::FirecrackerProcessBuilder;

let process = FirecrackerProcessBuilder::new("/usr/bin/firecracker", "/tmp/fc.sock")
    .id("my-vm")
    .no_seccomp(true)
    .cleanup_socket(true)
    .spawn()
    .await?;

let vm = process.vm_builder()
    .boot_source(/* ... */)
    .machine_config(/* ... */)
    .start()
    .await?;

// process is killed and socket cleaned up on drop

Via Jailer

use firecracker::sdk::JailerProcessBuilder;

let process = JailerProcessBuilder::new(
    "/usr/bin/jailer",
    "/usr/bin/firecracker",
    "my-vm",
    1000, // uid
    1000, // gid
)
.netns("/var/run/netns/my-ns")
.spawn()
.await?;

// Socket path is automatically computed from the chroot layout
let vm = process.vm_builder()
    .boot_source(/* ... */)
    .machine_config(/* ... */)
    .start()
    .await?;

Restoring from Snapshot

use firecracker::sdk::{restore, types::*};

let vm = restore(
    "/tmp/firecracker.sock",
    SnapshotLoadParams {
        snapshot_path: "/path/to/snapshot".into(),
        mem_file_path: Some("/path/to/mem".into()),
        mem_backend: None,
        enable_diff_snapshots: None,
        track_dirty_pages: None,
        resume_vm: Some(true),
        network_overrides: vec![],
    },
).await?;

Rebuilding from Exported Config

// Export config from a running VM
let config = vm.config().await?;

// Recreate a builder on a new Firecracker instance
let new_vm = VmBuilder::from_config("/tmp/new-fc.sock", config)
    .mmds_data(/* optional pre-boot MMDS data */)
    .start()
    .await?;

Bundled Runtime Mode

Enable this capability with:

cargo add firecracker --features bundled-runtime

firecracker::runtime::bundled supports resolving firecracker and jailer binaries from bundled Firecracker upstream release artifacts with optional fallback to system PATH. Release-based bundled mode currently supports:

  • linux-x86_64
  • linux-aarch64
use firecracker::runtime::bundled::{BundledMode, BundledRuntimeOptions};

let bundled = BundledRuntimeOptions::new()
    .mode(BundledMode::BundledThenSystem)
    .bundle_root("/opt/arcbox/bundled")
    .release_version("v1.12.1")
    .firecracker_sha256("sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
    .jailer_sha256("sha256:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789");

let fc = bundled.firecracker_builder("/tmp/firecracker.socket")?;

let jailer = bundled.jailer_builder("vm-1", 1000, 1000)?;

Supported bundled path layout:

  • {bundle_root}/release-vX.Y.Z-{arch}/firecracker-vX.Y.Z-{arch}
  • {bundle_root}/release-vX.Y.Z-{arch}/jailer-vX.Y.Z-{arch}
  • {bundle_root}/firecracker-vX.Y.Z-{arch}
  • {bundle_root}/jailer-vX.Y.Z-{arch}
  • {bundle_root}/{os}-{arch}/{binary}
  • {bundle_root}/{os}-{arch}/bin/{binary}
  • {bundle_root}/{arch}-{os}/{binary}
  • {bundle_root}/{arch}-{os}/bin/{binary}
  • {bundle_root}/{binary}

Environment variable overrides:

  • FC_SDK_FIRECRACKER_BIN
  • FC_SDK_JAILER_BIN
  • FC_SDK_BUNDLED_DIR
  • FC_SDK_FIRECRACKER_RELEASE

fc-cli usage examples:

# Resolve both binaries using bundled-first strategy
cargo run -p fc-cli -- resolve all --mode bundled-then-system --bundle-root /opt/arcbox/bundled --release v1.12.1

# Resolve only firecracker from system PATH
cargo run -p fc-cli -- resolve firecracker --mode system-only

# Start a microVM and keep fc-cli attached (Ctrl+C to stop)
cargo run -p fc-cli -- start \
  --mode bundled-then-system \
  --bundle-root /opt/arcbox/bundled \
  --release v1.12.1 \
  --kernel /path/to/vmlinux \
  --rootfs /path/to/rootfs.ext4 \
  --socket-path /tmp/firecracker.socket

# Start a microVM in detached mode
cargo run -p fc-cli -- start \
  --kernel /path/to/vmlinux \
  --rootfs /path/to/rootfs.ext4 \
  --detach

# Start a microVM via jailer in detached mode
cargo run -p fc-cli -- start \
  --backend jailer \
  --uid 1000 \
  --gid 1000 \
  --kernel /path/to/vmlinux \
  --rootfs /path/to/rootfs.ext4 \
  --detach

# Show platform support for release-based bundled mode
cargo run -p fc-cli -- platform

fc-cli start notes:

  • --backend firecracker: uses --socket-path (default /tmp/firecracker.socket).
  • --backend jailer: requires --uid and --gid; custom --socket-path is not supported.
  • --backend jailer --daemonize: must be used together with --detach.
  • --detach: leaves the process running and prints socket plus best-effort pid.
  • default (without --detach): keeps fc-cli attached; press Ctrl+C for graceful shutdown.

Building

Requires Node.js (for npx swagger2openapi during code generation).

cargo build

License

MIT OR Apache-2.0

Dependencies

~7–15MB
~251K SLoC