Table of Contents
Docker & Kubernetes vs. "The Nine Unix Philosophy Principles" (Mike Gancarz)
Mike Gancarz’s nine principles define the Unix Way: small, focused, composable, text-driven tools. Docker and Kubernetes claim to be “modern Unix” but both fail the Unix test hard.
Let’s evaluate both using Gancarz’s principles.
1. **Small is beautiful**
*“Small programs are easier to understand, maintain, and reuse.”*
| Docker | Kubernetes |
| Single binary: `docker` is a 100MB+ It's Daemon: `dockerd` is written in “Go” (oh yeah, we all learned “Go” right?) and is 200k+ lines of code. It requires root | 50+ microservices Control plane: 10+ binaries Typical cluster: 1000s of YAML lines |
| Fails | Fails spectacularly |
Verdict: Both are bloated. Docker is a fat daemon. Kubernetes is a distributed monolith.
2. **Make each program do one thing well**
“Focus on a single, well-defined task.”
| Docker | Kubernetes |
| Builds images, Runs containers, Pushes to registry, Manages volumes, Networks, Even `docker compose` | Orchestrates, Networks, Stores, Schedules, Secrets, CI jobs, Service mesh |
| Fails — does 5+ things | Fails — does everything |
Verdict: Neither respects single responsibility.
3. Build a prototype as soon as possible
“Fail fast, iterate.”
| Docker | Kubernetes |
| `docker run nginx` is instant, Fast feedback | 6-month release cycle, 3-month deprecation, Breaking API changes, `kubectl` syntax churn |
| Passes | Fails |
Verdict: Docker wins on speed. Kubernetes prototypes in production.
4. Choose portability over efficiency
“Write once, run anywhere.”
| Docker | Kubernetes |
| OCI images do run anywhere, but: host kernel matters (cgroups, namespaces) | Same YAML (in theory), But: CSI, CNI, cloud load balancers, node OS |
| Mostly passes | Fails in practice |
Verdict: Docker is more portable. Kubernetes is cloud-coupled.
5. **Store data in flat text files**
“Human-readable, grep-able, diff-able.”
| Docker | Kubernetes |
| `Dockerfile` — text, good, Images → tar layers, Config → JSON in daemon | Everything in etcd (not files), `kubectl get -o yaml` gives 300+ lines, No `grep /var/lib/kube/state` |
| Partially passes | Fails Miserably |
Verdict: Docker has text config. Kubernetes hides state in a database. Didn't we want computers working for us, not the other way around?
6. Use software leverage to your advantage
“Reuse existing tools. Compose.”
| Docker | Kubernetes |
| Reinvents `tar`, `chroot`, `iptables`, Replaces `rkt`, `lxc` | Reinvents `crontab`, `systemd`, `iptables`, `nginx`, `supervisord` |
| Fails | Fails worse |
Verdict: Both replace Unix tools instead of composing them. There really isn't an excuse, either. Just some blank stare and “but it's newer” which shouldn't hold water for anyone with critical thinking skills.
7. **Use shell scripts to increase leverage and portability**
“Glue tools with shell.”
| Docker | Kubernetes |
| `docker run` in scripts is OK `docker exec` is debug only | `kubectl exec` → not for workflows, >Helm/Kustomize replace shell, Operators in Go (It's a formerly trendy programming language like ADA and it's already fading out) |
| Uhhh, kinda | Fails |
Verdict: Docker allows shell scripts but doesn't really leverage them. Kubernetes discourages it.
8. Avoid captive user interfaces
“Don’t force a GUI. Let the user choose.”
| Docker | Kubernetes |
| CLI: `docker` GUI: Docker Desktop (optional) | `kubectl` is CLI But: Dashboard, Lens, K9s needed for sanity |
| Passes | Partially passes |
Verdict: Docker CLI is usable. Kubernetes CLI is unreadable without tools.
9. Make every program a filter
“Take input, produce output. Chain them.”
| Docker | Kubernetes |
| docker logs to text files and mostly respects text but Docker containers cannot use pipes like normal Unix programs. | `kubectl get pods -o json then pipe to jq`<br>But: no stdin for `apply`, `create` |
| Doesn't fail, exactly, doesn't pass either | Fails |
Verdict: Docker is pipe-friendly. Kubernetes is API-bound.
Final Scorecard
| Principle | Docker | Kubernetes |
|---|---|---|
| 1. Small is beautiful | No (100MB daemon) | No (50+ services) |
| 2. One thing well | No (build+run+net+vol) | No (does everything) |
| 3. Prototype fast | Yes (`docker run`) | No (6-month cycles) |
| 4. Portability > efficiency | Warning (kernel-dependent) | No (cloud-coupled) |
| 5. Flat text files | Warning (Dockerfile yes, state no) | No (etcd) |
| 6. Reuse tools | No (reinvents) | No (reinvents more) |
| 7. Shell scripts | Warning (possible) | No (discouraged) |
| 8. Avoid captive UIs | Yes (CLI first) | Warning (CLI unusable alone) |
| 9. Be a filter | Kinda (pipeable mostly) | No (not stdin/stdout) |
Docker: 3/9 Kubernetes: 0/9
I'm just going to have to ask… What is really gained here over more traditional solutions or even better, Unixy solutions?
Conclusion: Both Are "Anti-Unix"
Docker is a fat, root-requiring, daemon-heavy tool that mostly fails Unix principles.
Kubernetes is a distributed, YAML-bloated, shell-hostile, API-locked platform that fails every principle
They are not Unix tools. They are web-era, cloud-native, enterprise-grade abstractions built for scale, not simplicity or good engineering.