I've decided to write my own Docker

 

That’s what the title says. Now, if you’re a sane person, you’re probably wondering how I ended up in this situation.

Allow me to explain… I’ve been a software engineer for almost 30 years. I’ve been tinkering with programming for even longer.

Once upon a time, I did a lot of things that were objectively questionable but deeply educational.

Early in my “career”—when I was still in school and a 386 was a decent computer (the ex-USSR was still playing catch-up with modern times, and everyone was broke)—I was learning x86 assembly to poke video card registers directly. I had a very practical goal: my monitor was half-broken, and I needed to fix scan polarity and screen positioning just to get an image on the screen. All I had was a printout of Ralph Brown’s Interrupt List and a book on 8086 assembly. It was frustrating, time-consuming, and oddly satisfying in a way that modern abstractions rarely are.

Some time later, I wrote an undelete utility for FAT on PalmOS. It was about 80% finished and mostly worked. I never completed it—not because of technical difficulty, but because the platform simply disappeared. One day you’re reading file allocation tables and scanning clusters; the next day, the entire ecosystem is gone. The code is probably still sitting on some long-dead hard drive, faithfully unfinished.

Around the same time, I wrote a utility to inspect network packets to figure out how much data stayed within my ISP’s internal network. Internal traffic wasn’t metered, which led to a surprisingly vibrant content-sharing community living entirely inside the provider’s intranet. It was less about piracy and more about curiosity: understanding OSI model, IP, TCP and UDP headers. I was armed with MSDN and Wireshark—back when it was still called Ethereal.

None of this was particularly useful in a career-planning sense. But it taught me how systems fit together, where abstractions leak, and how much power—and responsibility—you have when you operate just one layer lower than you’re supposed to. All of that was at least 20 years ago.

Maybe it’s my age showing. Maybe it’s rose-tinted glasses. But at some point, I realized how much fun it used to be to work close to the hardware—or at least closer to the lower levels of a system. I don't do it anymore. Computers stopped to be simple and I, as most programmers, now float in the sea of abstractions, written by hordes of people, most of whom are smarter than me, and try to not look under the hood.

Sorry for the long rant—I am getting to the point, I promise.

I've asked an LLM model (yes, I do talk to LLMs, I find the experience interesting), how can I get back to system programming these days? It suggested to me that the good way will be to write something, like a FUSE filesystem or a container runtime.

Now, I’ve been using Docker for about 10 years. I have the general idea of how it works. As in: “It’s not a VM; it isolates a process so it looks like it runs on its own OS, but actually it runs on your main kernel. Oh, and cgroups.”

Which is to say: I don’t really know how it works. So I decided to learn a thing or two about how Docker actually works.

Did I mention I’m trying to learn Rust? A systems programming language designed to solve problems with C and C++. So why not kill two birds with one stone and implement a simple container runtime in Rust?

Well, “kill” is probably too strong a word, but at least I can try to inflict some amount of blunt-force trauma. And there’s also a third bird too—almost invisible, but suddenly very tempting: reliving that feeling of accomplishment you get when you learn something new and slightly arcane.

What could possibly go wrong™?

Armed with Rust, ChatGPT, Claude, and a number of man pages, I began my descent into the abyss.

I’m planning to write a diary of these adventures. Maybe I’ll even end up with something I can come back to later, when I need to remember what I actually learned—and how I learned it the hard way.

Other posts on these topics: