
From Docker to k3s — the decision to use Kubernetes for real
The keyword I didn’t know how to use
My resume went through an ATS (Applicant Tracking System) audit — the software that filters resumes before any human sees them. The score reached 98.8/100. Two keywords were missing: Automation (would be keyword stuffing — each language already has its own) and Kubernetes.
Kubernetes. The platform that orchestrates containers in production. Technical recruiters see that word and pay attention. And I didn’t use it. Putting it on my resume without using it would be a lie — and a technical lie is exactly what a good interviewer uncovers at the first question.
The alternative was worse: leaving it out and losing the match. So the decision was the only honest one: adopt Kubernetes for real.
The right question: where does it make sense?
Kubernetes isn’t a silver bullet. For a static site (Portfolio, LifeLog), it’s a huge overkill. For Jellyfin/TDarr (GPU passthrough, volumes, host networking), it’s a nightmare. But Arachne has a real microservice architecture:
| Service | Role |
|---|---|
arachne-api |
FastAPI — main API |
arachne-worker |
RQ queue (async jobs) |
nginx |
Reverse proxy |
crawl4ai |
Scraping sidecar |
redis |
Queues + cache |
postgres (pgvector) |
Data + embeddings |
umami + umami-db |
Analytics |
tunnel |
cloudflared |
backup |
Snapshots |
Ten services, queues, GPU, vector database. That’s exactly the kind of workload Kubernetes was built to orchestrate: worker isolation (a crash doesn’t take down the queue), rolling updates with zero downtime, self-healing (container dies → it comes back), native secrets.
The choice: k3s single-node
Options evaluated:
| Option | Verdict |
|---|---|
| k3s single-node | Chosen — real K8s, lightweight, real production |
| Homegrown multi-node cluster | Possible future (after it stabilizes) |
| k3d/kind (dev only) | Rejected — not production, doesn’t justify on the resume |
| Don’t adopt | Discarded — I want the real skill |
k3s (Rancher) is the lightweight Kubernetes distribution for edge — a single binary, under 100MB footprint, compatible with standard K8s. It runs on WSL2 without drama. It’s real Kubernetes: same API server, same kubectl, same manifest.
Accepted risks (and the stopping criterion):
- RAM is the critical resource: the host has 11GB total, ~3.7GB available. k3s overhead ~500MB-1GB. If it gets tight, STOP and report — never sacrifice production.
- GPU on WSL2 + K8s:
nvidia-container-toolkit+ device plugin (annoying config, but documented). - New maintenance: k3s updates, certificates.
The phased plan (with rollback at any moment)
The rule was simple: never break what’s working. The current Docker Compose stays intact until the last phase.
F0 Detailed plan (official k3s docs first)
F1 Install k3s + measure real RAM overhead
F2 Port stateless (api, worker, nginx, crawl4ai, redis)
→ running in PARALLEL with compose (different ports)
F3 Port stateful (postgres, umami-db) with migrated volumes
F4 GPU for the VLM worker + validate arachne-vlm-jobs queue
F5 DNS/tunnel cutover + turn off compose + monitor 72h
Each phase has a test with evidence: health check, RQ queue processing, RAG answering, VLM processing an image, umami collecting. No “it works” without proof.
Rollback: if any phase fails, it’s back to compose in minutes — it was never turned off.
Lessons (so far)
- Not lying on your resume is an architecture decision — the keyword became a real infrastructure driver. Honesty became a roadmap.
- Evaluate project by project — K8s only makes sense where the architecture demands it. Forcing it everywhere is fashion, not engineering.
- RAM as the stopping criterion — on a personal 11GB environment, overhead matters. Having an explicit limit prevents sacrificing production out of ego.
- Rollback is what gives you courage — knowing compose is intact until F5 lets you execute with confidence.
What’s next
The migration runs in phases, each one approved before execution. Once k3s stabilizes in production for 1-2 months, “Kubernetes (k3s)” goes on the resume for real. And the multi-node cluster (option B) is noted as a future experiment — first the single-node has to prove its value.