I set out to run some containers and accidentally became a platform team

I Set Out to Run Some Containers. I Accidentally Became a Platform Team.

TL;DR — Working almost entirely by talking to an AI, I set out to stop
losing track of homelab IP addresses and accidentally rebuilt most of modern
platform engineering: GitOps, infrastructure as code, a CMDB, runbooks, cert
automation, a service catalog, a product backlog, and living documentation. I
never followed a methodology. I just kept pulling the thread on each annoyance —
and every good fix turned out to already have a name, usually one with a
conference attached. This is that story, with a running translation of what each
thing actually was.

I need to confess something up front: I have never read a book about DevOps. I
couldn’t tell you the difference between a project and a program without looking it
up. And yet, over a few months of “hey, can you also…” sessions with an AI, I
rebuilt — badly at first, then not so badly — most of the discipline a real platform
team would recognize as their day job.

I didn’t set out to do that. I set out to stop losing track of which IP address I’d
given the last container. Everything else was me stumbling forward one annoyance at a
time, and only later discovering the thing I’d just invented already had a name.

Here’s the running translation.

What I called it, versus what the industry actually calls it

It started with a wiki, which turned out to be the point

The first decision — though it didn’t feel like one — was that every time the AI and
I built something, we wrote down the recipe, not the result: the prompt that
worked, the landmine we hit, the reason we chose one tool over another.

Those notes became a self-hosted wiki, and the wiki quietly became my most important
infrastructure, because it’s where the AI starts every session. It reads the
environment, sees the servers, the VLANs, the conventions — and stops being a generic
assistant and becomes my homelab’s assistant.

The part I’m proud of is kb_guide(). When the AI needs to do a specific thing —
deploy a container, document a project, file an idea — it doesn’t load a giant
manual. It pulls just that recipe, on demand. I thought I’d built a clever lookup
table. I’d actually built two things at once: technically a Skill (just-in-time
context), and conceptually a paved road — the “here’s the blessed way we do X
here” that platform teams build with tools like Backstage. I have a golden-path
internal developer platform. For a house. Because I got tired of re-explaining my
network every morning.

Then Komodo showed up, and it was CI/CD the whole time

The rule I landed on — from getting burned, not from a best-practices doc — was: the
only way to change a container is to change the repo.
Every compose file, every
variable, every stack definition lives in one Git repo. I push a commit, a webhook
fires, and Komodo reads a declarative config, syncs every stack, builds any custom
images, and deploys.

Push a commit and the pipeline does the rest: webhook, sync, build, deploy

I called this “container management.” When I finally wrote the wiki page for it, the
AI titled it “CI/CD Pipeline — Git-Native Container Deployment,” and I realized
I’d been living inside a term of art. The repo as single source of truth, reconciled
from a declared desired state? That’s GitOps. The declarative config file that
is the definition of every service? Infrastructure as Code. Push → webhook →
build → deploy? The CI/CD pipeline — the kind of thing consultants get paid to
draw out. Secrets resolved from a vault at deploy time, never in the repo? Secrets management — built
because putting a password in git felt gross, not because I’d read the guidance.

There’s even a deliberate gap: my deploy is a manual click, not automatic
reconciliation. I’d assumed that made it less mature. Turns out a human-in-the-loop
deploy is a change-approval gate, and plenty of shops pay to add one back in.

The IP addresses that taught me what “system of record” means

Here’s the original sin that started everything: I tracked every IP in an Excel
spreadsheet
. It was my system of record — right up until it wasn’t. The moment I
forgot to update a row it drifted from reality, and sooner or later two devices would
end up fighting over the same address while my spreadsheet swore everything was fine.

The fix escalated in a way that, in hindsight, recapitulated thirty years of
enterprise networking:

Every step away from the spreadsheet was a step deeper into enterprise networking

I stood up phpIPAM as the thing that knows which IPs are taken (an IPAM). I
put KEA in charge of DHCP in a high-availability pair, because if DHCP dies the
house goes dark (HA). I wired it so that before anything gets an IP, you ask the
system of record for a free one and reserve it — the AI does this now automatically
(IPAM-driven provisioning: allocate from the source of truth, never guess). Names
and certs went on top: DNS for resolution, and a reverse proxy that issues and
auto-renews Let’s Encrypt certificates over ACME — the protocol that does it
with no hands on the keyboard — while Duo MFA guards anything sensitive. That
stack has a name too: DDI (DNS, DHCP, IPAM as one discipline) plus certificate
automation. And a dashboard on top of that, so every service has a tile (a
service catalog).

I built a DDI stack, a PKI pipeline, and a service catalog. I did it because a
spreadsheet of IP addresses always drifts out from under you. Both things are true.

The documentation started writing itself

At some point the wiki got a split personality, and it’s my favorite thing in the
whole setup. There’s wisdom — the human-curated why a machine can’t regenerate.
And there’s facts — and the facts write themselves.

Facts regenerate from the live systems; humans only curate the wisdom

A small service polls the live systems and regenerates an inventory page: every
container, every IP, every DHCP lease, live. The page warns at the top: machine-
generated, do not hand-edit, fix the source of truth instead.
The governing rule:
if a fact here contradicts a live system, trust the live system and flag it.

I built this to stop maintaining a stale spreadsheet. I’d actually built a CMDB
continuously reconciled from the systems of record, with drift detection baked
into its philosophy. That “trust the live system” line is what expensive discovery
tools promise on their landing pages. Two more habits fell out of the same instinct:
every diagram is Mermaid — text that renders to a picture, so diagrams are
versioned and reviewed like code (diagrams-as-code) — and publishing runs through
a draft → stage → promote pipeline behind a human gate (docs-as-code, same
discipline as the software). I even rendered one deck as HTML, PowerPoint, and
Markdown from a single source: author once, render many.

Here’s that publish pipeline — drawn, naturally, in Mermaid, so the picture lives in
version control right beside the words it describes:

flowchart LR
  A["Author in Markdown"] --> C["checkpoint"]
  C --> S["publish → stage"]
  S --> R{"review"}
  R -->|looks good| P["promote → prod"]
  R -->|needs fixes| C

Runbooks, sprints, and a backlog that remembers

The methodology-that-wasn’t shows up in how work flows, too. Repeatable operations
become runbooks: parameterized, version-controlled, and executed by the AI, which
confirms each live change first — and if one doesn’t exist, the rule is do it
carefully, then capture it
so it’s reusable. That’s runbook-as-code and toil
reduction
, not “notes to myself.”

And when I build something real, the flow is always: build on the dev server, push to
DEV, then stop and live with it before it goes to prod — because there are always
changes, and rushing dev-to-prod is how you ship your own bugs. That stop-and-test
gate is UAT; the loop is a sprint; and the ideas I’m not ready for go into a
Futures backlog I can scope now and “graduate” later — a product backlog with
grooming. I even group related projects under “programs.” I picked the word because it
felt right. It’s the literal, formal definition. I stumbled into the vocabulary and it
was correct.

And then it jumped off the servers entirely

The strangest part is how far past “containers” this reached, using the same habits.
Home Assistant automations — motion lights, a Z-Wave watchdog that resets itself —
are documented and published like any other project (event-driven automation, as
code
). A tap-handle console designed in OpenSCADcode that compiles into a
physical object
— lives in the same doc pipeline (CAD-as-code). Album art pushes
to a 64×64 pixel panel. A WLED clock on the wall glances me the things I’d
otherwise go digging for — device states, and house stats like temperature and wind
speed. The network’s own health lives somewhere else: a NOC dashboard I built as a
web app, a live topology map that reads the UniFi controller directly. Both are
information radiators — status you catch in passing instead of setting out to look
for. And Plex is woven in so a physical record with an RFID tag starts the digital
version playing. None of these were “IT.” They were “wouldn’t it be cool if.” But they all
inherited the platform — an IP from the system of record, a GitOps deploy, a
self-documenting page — so the methodology I never learned turned out to be portable
to a tap handle.

The point, if there is one

I did not learn platform engineering and then apply it. I ran into problems, asked an
AI to help, and the good solutions kept converging on the practices professionals
already use
— not because either of us followed a framework, but because those
practices are what problems like mine push you toward if you keep pulling the thread
and refuse to accept “eh, it’ll probably be fine.”

GitOps exists because drift is painful. IPAMs exist because a spreadsheet always goes
stale. Runbooks exist because forgetting is painful. HA exists because outages are
painful. I
felt every one of those in miniature, in my own house, and re-derived the fixes from
first principles — then looked up and realized I’d reinvented an industry’s greatest
hits, one annoyance at a time.

I still haven’t read the DevOps book. At this point I’m a little afraid of how much of
it I’d recognize.

A footnote on how you’re reading this

In the spirit of the whole story, full disclosure: this post was a heavy lift
written by an AI
, working from my knowledge base — the same wiki this piece is
about — and then edited by me for the parts only I’d know (no, I wasn’t guessing
at IPs; I had a spreadsheet, thank you very much).

And publishing it turned into the most on-brand moment of the entire project. Getting
it onto www.cossaboon.net meant uploading images and creating the post — fiddly manual
steps I kept fumbling. So instead of fumbling, we built a new container: a small
MCP server that hands the AI a WordPress control plane — upload media, create the
post, set the featured image — deployed through the exact GitOps pipeline described
above. The AI then used its own brand-new tool to publish the post you’re reading.

The essay about accidentally building a platform got published by extending the
platform
. One more annoyance, one more tool. It never stops — and honestly, that’s
the fun of it.


Everything above is real and running. The deep version — including the AI prompts
that made each piece work — lives on my knowledge base.

About the Author

Kevin Cossaboon

A networking profesional located in Northren Virginia, USA. My hobbies are Technology and Photography. Love playing with the latest technology, and will try to post reviews of them. Also love my life long journey of learning to capture light, to trigger emotions, through photography.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.