Buried in a 276-comment Hacker News thread about what a "Kubernetes 2.0" should look like, a skeptic asked the question nobody building a Compose-based platform wants to hear. The founder of Rivet — an open-source serverless-actor platform — had just pitched his project as exactly that 2.0: an orchestrator engineers could self-host and scale trivially. The skeptic had read the self-hosting docs, and his reply was blunt: the options are a single container, Docker Compose, or manual docker run commands — "how is this a viable way to deploy serverless infrastructure … how is Docker Compose a better, more reliable and scalable alternative to Kubernetes?"
That question deserves a real answer, not a flame war. So here is the verdict up front, with the evidence below:
| Where you are | What wins | Why |
|---|---|---|
| One box, your own workloads | Rivet on Compose, or any single-node stack | One docker compose up, embedded state, nothing to orchestrate |
| A handful of boxes, your own workloads | Lightweight Kubernetes (K0s, K3s) + a PaaS layer like Kubero | You keep the Compose-like UX and gain scheduling, discovery, and rolling updates |
| A fleet, or other people's apps | Full Kubernetes with declarative machine lifecycle | Machines become desired state; tenants get real isolation boundaries |
The uncomfortable detail for the Compose side: Rivet's own documentation agrees with this table. The path from one machine to two is written down, step by step — and every step is a small admission that multi-machine orchestration is a distinct problem Compose was never built to solve.
The thread that started it
In June 2025, sysadmin-turned-writer Mat Duggan published a long essay asking what a Kubernetes 2.0 could look like after a decade of production scars: less YAML agony, native packaging, saner defaults — a platform engineers can "easily adopt and feel confident running themselves" while keeping a small core with strong primitives. The HN thread ran to 276 comments and 186 points, and the usual tribes assembled: kill-etcd minimalists, Compose romantics, "just use Nomad" realists, and people who have been paged enough times to flinch at all of them.
Into that arena walked Rivet's builder, with a credible claim to have built the thing: an orchestrator and deployment platform he could self-host and "scale trivially," open source, scratched from his own itch. This was not drive-by marketing. Rivet is a Y Combinator-backed company whose pitch is an open-source alternative to Cloudflare's Durable Objects — stateful "actor" infrastructure in Rust, running multiplayer game backends serving millions of monthly players, with auto-scaling, matchmaking, and DDoS mitigation. Its December 2024 Show HN ("Rivet Actors — Durable Objects built with Rust, FoundationDB, Isolates") landed well because the pedigree was real: this team runs stateful workloads at scale for a living.
So the skeptic's challenge was aimed at a serious target, which is what makes it worth answering seriously. He wasn't disputing that Rivet works. He was disputing that docker compose up is a multi-machine strategy — and offering to convert the docs to run Rivet on Kubernetes himself to prove the point.
Steelman: what Rivet gets right on one box
Before the critique, the credit. Rivet's self-hosting story on a single machine is genuinely excellent, and it is exactly what the Kubernetes-2.0 thread was asking for:
- One artifact to run. The engine ships as a single Rust binary or container (
docker run -p 6420:6420), with Compose files for dev, multi-datacenter dev, and production layouts. No control plane to bootstrap, no etcd quorum to babysit, no CNI to debug. - Embedded state by default. On a single node, actors persist to a filesystem backend built on RocksDB — local disk, zero external dependencies. Your platform's state lives next to your platform.
- A programming model above containers. Actors with RPC, state, and events are a higher-level primitive than "a container that restarts." For agentic and realtime workloads — Rivet's home turf — that abstraction does more daily work than any orchestrator feature.
None of that is in dispute. A solo team deploying game lobbies or agent sandboxes on one beefy VPS should absolutely start here and not feel a flicker of guilt. The dispute begins the week that box fills up.
The core deliverable: what machine two actually costs
Here is the part the thread never spelled out, so let's do it from Rivet's own self-hosting documentation. Going from one engine node to two is not "run Compose twice." It is four concrete steps, each converting something Compose gave you for free into something you now operate:
1. Evict the embedded database. RocksDB lives on local disk and cannot be shared between hosts. The docs say this plainly: single-node deployments use the filesystem backend; multi-node deployments must move to PostgreSQL. Your zero-dependency setup just gained a stateful service with backups, failover, and version upgrades to plan.
2. Add a message bus. Engine nodes coordinate through NATS for pub/sub. On one box this is invisible; on two, it is another distributed component with its own clustering, persistence, and monitoring story. Count your new moving parts: Postgres, NATS, plus the engines themselves.
3. Accept the documented ceiling. The docs describe PostgreSQL as "production-ready for light-to-moderate workloads, up to roughly 1,000 concurrent actors" — and explicitly "not built for enterprise scale beyond that." That number is refreshingly honest, and it is also a wall. A thousand concurrent actors covers a lot of games and side projects; it does not cover the workload growth curve that made you add machine two in the first place.
4. Call the vendor for the real backend. Past the Postgres ceiling, the documented answer is FoundationDB — "contact enterprise support." FoundationDB is superb technology and also famously operationally demanding; at that point the self-hosting story has quietly become a sales conversation.
Read that sequence again and notice what happened: the platform reinvented, piece by piece, the state and coordination layer that Kubernetes ships as table stakes (etcd, with quorum, backups, and a decade of runbooks).
Meanwhile the placement layer — which node runs which actor, what happens when a host dies mid-match, how a rolling engine upgrade drains connections — remains the operator's homework. Compose starts containers where you point it. It does not bin-pack, reschedule, or heal. Those are not missing features; they are a different product category.
The skeptic's question, answered with a table
"How is Docker Compose a better, more reliable and scalable alternative to Kubernetes?" Strictly: it isn't, across machines — and Rivet's docs never actually claim it is. The claim in the thread is easier to adopt and feel confident running, which is a different virtue, and a real one. Reliability and scalability across hosts come from mechanisms, so let's score the mechanisms:
| Multi-machine need | Docker Compose | Kubernetes (+ Cluster API) |
|---|---|---|
| Bin-packing workloads onto hosts | Manual: you assign services to boxes | Scheduler with requests, limits, affinity, and descheduling |
| Cross-host service discovery | Hand-wired hostnames or an external load balancer | Cluster DNS, Services, and ingress as built-in objects |
| Rolling updates without downtime | Scripted pull-and-restart per box, connection draining is yours | RollingUpdate strategy with readiness gates and automatic rollback |
| Declarative machine lifecycle | None: new hosts arrive via SSH and install scripts | MachineDeployments: fleet shape as desired state, controllers reconcile |
Every row in the left column is a runbook; every row in the right column is an object you can review, diff, and roll back. That is the whole ballgame once the fleet outlives any single operator's memory. Compose wins the adoption battle so completely that it is tempting to mistake adoption for architecture — but "I understood it in an afternoon" stops being evidence at the exact moment the pager goes off for a host you didn't personally configure.
Where K0s lands: the actual middle path
The thread's best answers understood that the choice was never really Compose or Kubernetes. The interesting territory is Kubernetes with the adoption cost sanded off — and that project already exists.
K0s, Mirantis's "zero-friction Kubernetes," ships the whole distribution as a single binary with no host OS dependencies beyond the kernel; clusters bootstrap in minutes. Since May 2025 it sits in CNCF Sandbox alongside K3s, which keeps it inside the ecosystem instead of forking away from it. Three facts matter for this debate:
- It keeps the full API. Every manifest, operator, and Helm chart written for Kubernetes runs unmodified — including, pointedly, anything that would host Rivet's engine containers with real scheduling and service discovery.
- Multi-node needs no second state system. Joining a worker is a token and a command, not a Postgres migration plus NATS cluster. The control-plane state problem stays solved once, by etcd, instead of once per platform layer.
- The PaaS UX is a layer, not a fork. Kubero puts the Heroku-style dashboard, CLI, and GitOps deployment flow on top of any Kubernetes cluster as two containers (UI plus operator), storing its state in etcd with no extra database. That is the Compose-grade experience — click-to-deploy, buildpacks, preview apps — without surrendering the orchestrator underneath.
This is why the "Kubernetes 2.0" framing slightly misses its own point. The 2.0 the thread wants — trivial to install, confident to run, small core, strong primitives — is not a rewrite of the orchestrator. It is a thin, opinionated PaaS UX over a boring, standard orchestrator. K0s plus a Kubero-style layer is that shape today; Rivet's engine running on that shape, rather than beside it on raw Compose, is arguably what the skeptic was volunteering to build.
One box vs a fleet is the only distinction that matters
Strip the thread to its load-bearing wall and it reads like this: starting simple and staying simple are different advice. Rivet on Compose is among the best "start simple" stories in open source — a serious engine, honest docs, a stated ceiling. Kubernetes (via K0s at the small end, Cluster API machine lifecycle as the fleet grows) is the "stay simple at machine N" story, where N is bigger than one and the simplicity is in operations, not installation.
So: if your actors fit on one box with headroom, stop reading and ship on Compose. If you can see machine two from here — or you host apps written by people who don't work for you — put the boring orchestrator underneath on day one, while the migration is still a weekend project instead of a postmortem action item.
Running that second scenario — a git-push PaaS on machines you own, with declarative fleet lifecycle instead of SSH runbooks — is exactly what Bex.co is building in the open. Star the repo or bring your own Hetzner boxes; the Compose tutorial stays one page, and machine two stays boring.



