Mini ContainerD is an educational project where Iβm building a minimal container runtime from scratch in Go. The goal is to understand how containers actually work under the hood β beyond Docker abstractions β by directly working with Linux primitives like namespaces, mounts, and process isolation.
This is not meant to be production-ready. Itβs a learning project focused on exploring systems programming and container internals.
At its current stage, the runtime can:
- Create isolated environments using Linux namespaces (PID, UTS, mount)
- Set a custom hostname inside the container
- Switch the root filesystem using
pivot_root - Execute a process inside the container
- Mount basic filesystems like
/proc - Provide a minimal shell environment using BusyBox
Running a container drops you into a shell that is isolated from the hostβs process tree and filesystem.
Inside the container:
/ # ps
PID USER TIME COMMAND
1 root 0:00 /proc/self/exe child bundle
6 root 0:00 /bin/sh
9 root 0:00 psOnly container processes are visible, which confirms PID namespace isolation.
.
βββ main.go # Core runtime implementation
βββ bundle/
β βββ config.json # OCI-like runtime configuration
β βββ rootfs/ # Container root filesystem
The runtime follows a simplified version of how tools like containerd/runc operate:
- Load container configuration (
config.json) - Re-execute itself as a child process
- Create new namespaces (PID, UTS, mount)
- Set up the root filesystem using
pivot_root - Mount required filesystems (
/proc, etc.) - Execute the container process
The parent process acts as a launcher, while the child process becomes PID 1 inside the container.
- Linux (tested on Fedora)
- Go installed
- Root privileges (required for namespaces and mounts)
go build -o mini-containerdsudo ./mini-containerd run bundleThis project currently uses a minimal BusyBox-based root filesystem.
A static BusyBox binary is used to avoid dependency issues inside the container.
This is still a work in progress. Some known limitations:
/devis not fully implemented yet- No cgroup support (no CPU/memory limits)
- No networking isolation
- Minimal error handling in some areas
- Basic process lifecycle handling
This project is part of my effort to get deeper into systems programming and distributed systems tooling. Instead of treating containers as black boxes, I wanted to understand:
- How process isolation actually works
- How filesystems are switched and mounted
- How runtimes like runc/containerd are structured
Some of my other educational projects:
- stream β https://github.com/xonas1101/stream
- logger-controller β https://github.com/xonas1101/logger-controller
Early prototype, but functional.
Still actively improving and adding features.
This is a working demo of containerd container runtime