Rémi Pelloux / case study / Containust

Case study

Containust

A container runtime in Rust with no background daemon, built for machines where a daemon, a registry or hidden state is a liability.

Containust banner with a terminal running ctst pull
The project banner: no daemon, declarative stacks, ready for air-gapped machines.
Role
Author and maintainer
Stack
Rust, nom, petgraph, Linux namespaces, cgroups v2, QEMU
Hosts
Linux x86_64 and aarch64, macOS, Windows
Source
github.com/RemiPelloux/Containust

Problem

Docker needs a root daemon that has to stay alive, and it expects a registry to be reachable. On an air-gapped or security-critical machine both are a problem. Containust removes the daemon and makes offline the enforced case.

What I built

  • A command, ctst plan, that shows what would be created, replaced, started, kept or removed before anything runs.
  • A small typed language for stacks, .ctst, validated before execution.
  • An --offline flag that refuses the network before any connection opens, with images pinned by digest.
  • Secure defaults: user and PID namespaces, every capability dropped, no_new_privs, a read-only root filesystem.
  • A Rust SDK that exposes the parser, the dependency graph, the planner and the runtime.

How it works

A nom grammar parses the stack file and petgraph sorts the services so upstreams start first. The planner diffs the wanted state against the running containers. On Linux, the runtime forks into user, PID, mount, network, IPC and UTS namespaces, applies cgroups v2 limits and pivots into the root filesystem. On macOS and Windows the same requests go over JSON RPC to an agent inside a pinned Alpine QEMU virtual machine.

Limits

It does not build from a Dockerfile: it imports a root filesystem, a tar archive or an OCI image. It pulls from Docker Hub and GHCR only, and it has no orchestration. Linux needs kernel 5.10 or later, the other hosts need QEMU 7.

All selected work Next: Modelly