A declarative CLI tool to build Debian-based rootfs images using mmdebstrap and YAML manifests
rsdebstrap builds Debian/Ubuntu root filesystems from a single declarative YAML
profile. It wraps the standard bootstrap tools (mmdebstrap, debootstrap) and
adds a post-bootstrap provisioning pipeline — mounts, DNS setup, shell scripts,
and mitamae recipes — each step run
in its own isolation context with optional privilege escalation.
Instead of a bespoke build script per image, you describe the whole build once
and run rsdebstrap apply.
- Declarative — the entire rootfs build lives in one YAML profile.
- Multiple backends —
mmdebstrapordebootstrap. - Three-phase pipeline —
prepare→provision→assemble, run in order. - Provisioners — inline or external shell scripts and mitamae recipes.
- Per-task isolation & privilege — chroot isolation by default, with optional
sudo/doasescalation, both overridable per task. - One privilege boundary — rootfs modifications go through a single helper
process spawned once per run, not a
sudoper file operation, and resolve every path component withO_NOFOLLOWso a planted symlink cannot redirect a privileged write. - JSON Schema — a committed schema for editor completion and validation.
- Shell completions — bash, zsh, fish, powershell, elvish.
At runtime rsdebstrap invokes external tools, so at least one bootstrap backend
must be on your PATH:
mmdebstrapordebootstrap— the bootstrap backend (required; the chosen backend is checked onPATHbefore running).sudoordoas— only when a profile requests privilege escalation (required when mounts are configured). rsdebstrap re-executes itself under it once per run to serve rootfs modifications, in addition to wrapping the commands that need root.- A
mitamaebinary — only when a profile uses themitamaeprovisioner.
Building from source additionally requires Rust 1.97+ (edition 2024). This
minimum supported version is declared as rust-version in Cargo.toml, so
cargo and downstream packagers can read it directly.
rsdebstrap is not yet published to crates.io, and no prebuilt binaries are available yet — install from source for now.
With cargo, install the latest directly from Git:
cargo install --git https://github.com/takumin/rsdebstrapOr build a local checkout:
git clone https://github.com/takumin/rsdebstrap
cd rsdebstrap
cargo build --release
# binary at target/release/rsdebstrapPrebuilt, signed binaries for multiple Linux targets (gnu/musl across x86_64, i686, aarch64, armv7) are attached to GitHub Releases once a version is tagged.
From a checkout, try it against the bundled example profile:
# Validate a profile (syntax + schema, no bootstrap)
cargo run -- validate -f examples/debian_trixie_mmdebstrap.yml
# Preview the bootstrap command without executing it
cargo run -- apply -f examples/debian_trixie_mmdebstrap.yml --dry-runWith the installed binary, the core commands are:
# Validate, then dry-run, then build for real
rsdebstrap validate -f profile.yml
rsdebstrap apply -f profile.yml --dry-run
rsdebstrap apply -f profile.yml-f/--file defaults to profile.yml, and -l/--log-level controls
verbosity (trace, debug, info, warn, error; default info).
# bash (add to ~/.bashrc)
eval "$(rsdebstrap completions bash)"
# zsh (save to a completion directory)
rsdebstrap completions zsh > ~/.zsh/completion/_rsdebstrapCompletions are available for bash, zsh, fish, powershell, and elvish.
Print the profile schema (generated from the Rust config types) — useful for editor completion and validation:
rsdebstrap schema > rsdebstrap.schema.jsonA profile declares an output directory, optional defaults, a bootstrap
backend, and the prepare / provision / assemble pipeline phases:
dir: /tmp/debian-trixie
bootstrap:
type: mmdebstrap
suite: trixie
target: rootfs
provision:
- type: shell
content: |-
#!/bin/sh
set -e
apt-get update && apt-get install -y vim- Full annotated example:
examples/debian_trixie_mmdebstrap.yml - Machine-readable schema:
schema/rsdebstrap.schema.json - Field-by-field reference:
docs/PROFILE.md - Internal design and invariants:
docs/ARCHITECTURE.md
Contributions are welcome. Build with cargo build, run the test suite with
cargo test --workspace, and see AGENTS.md and
docs/ARCHITECTURE.md for the development commands and
architecture before making changes. After changing any config type, regenerate
the committed schema with task schema (CI enforces this).
Licensed under the Apache License 2.0.