In Progress

Deacon

A fast, focused Rust implementation of the DevContainer CLI — the consumer commands, verified against the reference CLI scenario by scenario, plus the security and configuration capabilities it doesn't have.

Deacon robot mascot - a tall elegant silver robot, surrounded by Rust and container icons

Overview

Deacon is a Rust implementation of the Development Containers CLI, following the containers.dev specification. It ships as a single native binary with no Node.js runtime, which makes it cheap to drop into CI images and constrained environments. It implements the consumer half of the spec — the commands you run to use a dev container, not the ones you would run to author one. Feature authoring and template publishing are out of scope by design, which is what keeps the surface small enough to verify.

Which raises the only two questions that matter for a reimplementation: can you trust it to behave like the tool it replaces, and what do you get that the original doesn't give you?

How You Know It's Right

Deacon is a reimplementation, so "is it correct?" is really two questions: does it match the pinned containers.dev spec, and does it match the pinned reference CLI (@devcontainers/cli v0.87.0)? Those can disagree — and sometimes deacon differs from both on purpose.

The instrument is one sentence: run both CLIs over the same scenarios, normalize the outputs, and diff them. Every difference is either a bug with an issue number or a documented choice with an allowlist entry. Nothing sits in between, and every bug found in the wild becomes a scenario before it gets fixed.

The result is a behavior-by-behavior ledger, each row carrying its own evidence — including a status for the case that trips people up, where deacon follows the spec and the reference deviates. That is the reference's divergence, not work deacon owes.

Where Deacon Goes Further

Matching the reference is the floor, not the ceiling. Deacon adds capabilities the reference CLI has no equivalent for — and records each one as an explicit extension, so they are never confused with drift.

extends chains - Layer configurations across files and deacon resolves the whole chain — base image, merged containerEnv and forwardPorts — for up, build, and read-configuration --include-merged-configuration. This is ahead of the spec, tracking in-flight proposal devcontainers/spec#22; the reference does not resolve extends at all.
Teardown - down stops a container or an entire Compose project, honoring the config's shutdownAction; --remove tears it down for real, and --all sweeps every container deacon created. The reference CLI has no teardown command at all.
Corporate CA injection - --inject-host-ca installs your host's root CAs into the container's trust store, at build time and at runtime — so the tools running inside your dev container work behind a corporate TLS-inspecting proxy.
Workspace trust for host-side hooks - initializeCommand runs on your machine, before any container exists to sandbox it. Deacon refuses to run it unless you have said the workspace is trusted — --trust-workspace for one run, --trust-workspace-persist to remember it, or DEACON_NO_PROMPT=1 to fail closed in CI. Untrusted is the default and there is no prompt to click through. The spec does not mandate any of this.
Feature refusal - Name a Feature and deacon refuses to install it, on up and build alike, before it touches a registry or a daemon. Matching is by prefix terminated at an id separator, so .../features/node covers every version and variant of it without also catching .../nodejs. Point --control-manifest at a file in your own repository to keep the list under review, or at a URL to inherit one.
.env secrets files - --secrets-file takes flat JSON or the KEY=VALUE file you already have sitting next to your Compose setup. The reference accepts only JSON.

The Full Consumer Surface

Everything the spec asks a consumer CLI to do, it does — so nothing above comes at the cost of the basics.

up / exec / down — full container lifecycle with every phase (onCreate, postCreate, postStart, postAttach), idempotent operations, and state persistence.
read-configuration — complete devcontainer.json parsing with variable substitution and Docker Compose multi-service orchestration.
build — Dockerfile-based builds with BuildKit integration for secrets, SSH forwarding, caching, and multi-architecture output.
Feature installation — OCI-published features installed during up and build, with dependency resolution, parallel installation, and a committed devcontainer-lock.json. upgrade regenerates the lockfile; outdated reports current, wanted, and latest.
run-user-commands, set-up and templates apply — run lifecycle hooks in an existing container, convert an already-running container into a DevContainer, or scaffold a project from a published template.
doctor — validates Docker availability, disk space, CPU, and memory, with JSON output for automation.

Use Cases

Deacon excels in these scenarios:

CI/CD pipeline integration with fast startup, JSON output modes, and no Node.js to install
Locked-down and enterprise environments needing CA injection, workspace trust, or a Feature allowlist
Standardizing team development environments with version-controlled configurations
Layered, multi-file configurations that the reference CLI cannot resolve
Open-source project onboarding with single-command setup
Migrating from VS Code Dev Containers to CLI-first workflows

Technical Highlights

Built in Rust (Edition 2024, MSRV 1.95) using tokio for async I/O, reqwest with rustls for OCI registry operations, and clap for CLI parsing. The architecture separates the CLI binary from the core domain library, with abstractions like ContainerRuntime (Docker/Podman), ConfigLoader (extends chain resolution), and FeatureInstaller (OCI installation with dependency resolution). Podman is not an afterthought: a required CI lane runs the full integration suite against rootless Podman, with GPU passthrough the one remaining gap. Performance optimizations include container environment probe caching and parallel feature installation.

Getting Started

Install via curl: curl -fsSL https://get2knowio.github.io/deacon/install.sh | bash. Run deacon up --workspace-folder . in any directory with a .devcontainer/devcontainer.json to start a development container. Use deacon exec -- <command> to run commands inside, and deacon doctor --json for system diagnostics. Releases ship eight targets — Linux gnu and musl, macOS, and Windows, each on x86_64 and aarch64 — with per-archive SHA256 checksums, SPDX SBOMs, and SLSA build provenance.

Technologies

rustdevcontainersdockerclideveloper-toolsoci