A container runtime built from scratch in Rust to learn systems programming fundamentals.
Bento is an educational container runtime that implements core container isolation mechanisms found in production runtimes like Docker, containerd, and youki. This project exists to deeply understand how containers actually work under the hood.
- Parses OCI-compliant container images
- Creates isolated container environments using Linux namespaces
- Implements overlay filesystem for copy-on-write functionality
- Manages container lifecycle (create, start, stop, kill, status, exec)
- Provides process isolation and filesystem isolation
Note
This demonstration uses the linux kernel.
You'll need to be on a linux machine, linux vm, use wsl2, or in container with root privileges.
Requires Docker to pull OCI-compliant images
Make the directories to house all your bento containers and use Docker to pull and tar images.
The example below demonstrates creating a busybox container.
mkdir -p ~/.bento/containers
mkdir -p ~/.bento/images
docker pull busybox
docker save -o ~/.bento/images/busybox.tar busyboxClone or fork the repo to create and start your first container.
git clone https://github.com/CarloQuick/bento.git
cd bento
mv .env.example .envIn your .env file, you will find 3 entries. You only need to add the value for BENTO_DIR. Here will be the base location for containers an images.
BENTO_DIR=
BENTO_IMAGES_PATH=${BENTO_DIR}/images
BENTO_CONTAINERS_PATH=${BENTO_DIR}/containersBy default, bento containers are rootless, so you can create containers without giving the process sudo permissions.
cargo run -- create busybox-container busyboxCheck the container to see its status.
cargo run -- status busybox-containerNote: Bento doesn't yet implement PTY forwarding, so start will leave your terminal in a broken state. Open a second terminal before running start, then use exec to interact with the container.
cargo run -- start busybox-containerIn a new terminal in the same directory:
cargo run -- exec busybox-container ls -laTo end the process, you can gracefully end or kill it by name.
cargo run -- stop busybox-containeror
cargo run -- kill busybox-containerIsolation mechanisms:
- User namespaces (rootless container execution)
- PID namespaces (isolated process trees)
- Mount namespaces (isolated filesystem)
- UTS namespaces (isolated hostname)
Filesystem handling:
- OCI image format parsing (index.json, manifest.json, config.json)
- Layer extraction and overlay filesystem mounting
- Container-specific upperdir/workdir/merge directories
Current functionality:
create: Parse OCI image, extract layers, configure container filesystemstart: Fork process into isolated namespaces, mount overlay filesystem, execute container commandstop: Gracefully end a containerkill: Forcefully terminate a containerstatus: Check container stateexec: Run command in already running container
Container runtimes sit at the intersection of operating systems, filesystems, and process management. Building one requires understanding:
- Linux syscalls and kernel interfaces
- Filesystem layering and mount mechanics
- Process forking and namespace isolation
- OCI image specifications
- Systems-level error handling in Rust
This is a learning project focused on depth over features.
Experimental - This runtime is not production-ready and should not be used in production environments. It exists purely for educational purposes and to demonstrate understanding of container internals.
- Rust
- Linux namespaces (via
nixcrate) - OCI image format specifications
This project was built by working through:
- OCI Runtime Specification
- Linux namespaces and cgroups documentation
- Production runtime codebases (youki, runc)
- The Rust Programming Language book
Bento: containers compartmentalized like a bento box