DEV Community

Cover image for I Built My Own Container Runtime from Scratch Using Only Linux (No Docker, No containerd, No LXC)
Santhosh
Santhosh

Posted on

I Built My Own Container Runtime from Scratch Using Only Linux (No Docker, No containerd, No LXC)

I’ve been using Docker for a while, but at some point I realized I didn’t actually understand what it was doing under the hood.
How does a process suddenly get its own filesystem, its own network, its own environment?

So instead of reading more blogs, I decided to build it myself.
No Docker. No containerd. No LXC.
Just namespaces, cgroups, networking, and filesystem isolation.

That’s how I ended up building LXR (Linux Container Runtime) written in Go, using only Linux primitives.

The idea

Build containers from scratch and make them usable for real development.

LXR not only creates containers, but also lets you work inside them directly from the browser or terminal, while the runtime handles everything underneath.

So LXR can:

  1. pull images from Docker Hub
  2. extract rootfs
  3. create isolated containers
  4. configure networking (veth + bridge + IP allocation)
  5. provide shell access via lxr exec
  6. run code-server inside containers for browser access

Using it

From the outside, it looks simple:

lxr create --name goCon golang
Enter fullscreen mode Exit fullscreen mode

But internally, this triggers a full setup.

What actually happens:

  1. image layers are pulled
  2. dependencies are installed into the image rootfs
  3. root filesystem is prepared
  4. overlay filesystem is created
  5. networking is configured
  6. IP is allocated
  7. container process is started
  8. code-server is launched

All of this... just to start one container.

Result

Once containers are running:

lxr ps
Enter fullscreen mode Exit fullscreen mode

Each container has:

  1. its own PID
  2. its own IP
  3. its own network namespace
  4. its own filesystem (OverlayFS)

At this point, LXR behaves as an real container runtime.

The first problem

The first issue wasn’t networking or filesystem.
It was just starting a process.

I tried running containers as a non-root user, but it didn’t work the way I expected.Processes failed to start or behaved inconsistently due to restrictions.

This turned out to be related to how Linux handles namespaces and permissions.

I’ll cover that part in the upcoming post.

Top comments (0)