Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
containerization-framework
Rust bindings for Apple's Containerization framework: Linux containers.
use containerization_framework as cfw;
use ;
let cache = new;
let store = at;
let session = new;
let mut spec = new;
spec.vm = VmResources ;
spec.configuration.cpus = 4;
spec.configuration.memory_in_bytes = 4 << 30;
spec.configuration.process = new;
spec.configuration.interfaces = vec!;
spec.configuration.dns = Some;
session.boot?;
let code = session.exec?;
A container belongs to the process that booted it and dies with it. Nothing lists containers, though other processes may join running ones.
Requirements
- macOS 26 on Apple silicon, and Xcode 26 to build.
- Network on a first build: the build script compiles the bundled Swift package,
which resolves Containerization and its dependencies through SwiftPM. Versions
are pinned by the
Package.resolvedthat ships with this crate.
On non-macOS platforms, this crate compiles but returns errors on every call.
Codesigning
A binary using this crate must carry the com.apple.security.virtualization
entitlement. Without it Virtualization.framework refuses to start a VM, and
Session::boot fails saying so.
A containerization.entitlements file ships with this crate; binaries compiled
against containerization-framework should pass it, or a copy of it, to codesign
after compilation.
Signing ad hoc (--sign -) satisfies the entitlement but gives the binary a new
code identity on every rebuild, so anything keyed to that identity — Keychain
access, for one — prompts again. Sign with a development identity to keep it
stable.
A rebuild drops the signature, so this runs after every build.
Linking
The Swift runtime this links against is dynamic and referenced as
@rpath/libswift_Concurrency.dylib, which dyld resolves against /usr/lib/swift
in macOS. Anything that links this crate — a binary of yours, and the
test binaries of any crate of yours that links it — needs that rpath, or it
links and then dies in dyld at launch.
A build script's link arguments reach only its package's targets, so the rpath
belongs in .cargo/config.toml, where a rustflag covers every kind of target:
[]
= ["-C", "link-arg=-Wl,-rpath,/usr/lib/swift"]
Shape
- [
Store] is an image store on disk, in Containerization's layout. - [
Builder] provisions it (a kernel and thevminitdinit image) and turns a [BuildPlan] into an image: pull the base, unpack it to a writable ext4 block, boot it, run each step, and store the result as a single-layer image. No daemon, no builder image, no Dockerfile. - [
Session] boots a [BootSpec]'s container from an image and runs processes in it.
Configuration types in model mirror Containerization's
(LinuxContainerConfiguration, LinuxProcessConfiguration, Mount, ...), with
the same names and defaults, so its documentation applies. One difference:
fields the image seeds (arguments, working directory, user) are Options, and
None keeps the image's.
Build caching is by rootfs snapshot rather than by layer: a rebuild resumes from
the deepest step whose cache_key still matches. This crate only stores and
compares them -- caching, cache invalidation, etc. are the responsibility of
callers.
Unimplemented
The framework is larger than these bindings. Not exposed: signals to a guest
process, LinuxPod (several containers in one VM), container statistics,
filesystem freeze/thaw/trim, host↔guest file copy, registry authentication and
push, OCI layout import/export, per-process rlimits and capabilities, and Rosetta
(so no linux/amd64 — arm64 only).
An OCI runtime (and so seccomp) is configurable, but requires an init image with
runc, which Apple does not publish. Pass one's reference to Store::at.
Versioning
The Containerization release and the kernel are pinned separately, and a
mismatch fails at runtime rather than at build time. Session::version() names
both.
The pins are public (KERNEL_VERSION, KERNEL_URL, INITFS_VERSION,
INITFS_REFERENCE). As in Containerization, the caller chooses where the kernel
and unpacked init image live (Store::at). Provisioning fills empty paths and
leaves existing files alone, so name paths for the pinned versions, as above,
to pick up upgrades. Another init image must carry the pinned release's
vminitd.
Testing
cargo nextest run runs the unit tests.
The suite in tests/ boots real containers, so it sits behind the integration
feature and runs through bin/dev/test-integration, which signs each test binary
with containerization.entitlements first — the entitlement is checked against the
calling process.
Those tests share an image store at ~/.cache/containerization-framework-tests,
kept between runs. The first run fills it — a kernel download, the init image, and
a small image built from alpine:3 — so it needs the network; later runs reuse it.
This directory can be deleted.
License
MIT. Containerization itself is Apache-2.0 and is fetched at build time, not vendored here.