Open any 2026 "best self-hosted Heroku alternative" roundup and you will see the same lineup: Coolify, Dokploy, Dokku, CapRover, ranked side by side on stars, templates, and UI polish as if they were interchangeable answers to one question. This year's verdicts are typical of the genre — one 2026 showdown calls Coolify "the safest all-purpose pick," Dokploy the lean Swarm-native panel, and CapRover the stability choice — graded, in other words, as four flavors of the same thing.
They are not the same thing. Most of the tools in that lineup are panels over Docker daemons you provisioned by hand; almost none of them is a fleet. Once you see the three buckets — box panels, Swarm clusters, Kubernetes fleets — the roundups read less like buyer's guides and more like category errors with screenshots.
The map: three buckets, one table
Here is the whole landscape in one table. Bucket is what the tool is; the other columns are how you can tell.
| Tool | Bucket | What schedules your app | Who provisions machines | Multi-node / HA story |
|---|---|---|---|---|
| Dokku (~32K stars, MIT) | 1 — box panel | Plain Docker on one host (a k3s scheduler plugin exists for the adventurous) | You, by hand | None by default; scaling means a bigger box |
| Coolify (50K+ stars, Apache-2.0) | 1, reaching for 2 | Docker per server; Swarm mode experimental | You — you add each server to the dashboard | Manages many servers, but does not cluster-schedule across them; v5 promises a custom multi-server layer |
| Dokploy (~35K stars, open core) | 1, reaching for 2 | Docker Compose natively, Traefik in front; Swarm for multi-node | You — you join each node | Real Swarm clustering when you opt in; enterprise SSO/audit live behind a commercial license |
| CapRover (~15K stars) | 2 — Swarm cluster | Docker Swarm, always | You — you join each node | Swarm scheduling plus a marketplace; true HA still needs a 3-manager quorum you operate |
| Porter | 3 — Kubernetes fleet | Kubernetes | Porter — it stands up the cluster, VPC, load balancer, registry | Kubernetes-native, inside your own cloud account |
| Kratix-style platforms, bex | 3 — Kubernetes fleet | Kubernetes | Declared machines via Cluster API, not clicked-up VPSs | Kubernetes-native, on machines you own |
Two things to notice. First, every tool in the roundup top four lives in bucket 1 or 2. None of them provisions a machine: at every step, you rent the VPS, paste its IP, and join it to something. Second, the Swarm callout matters: CapRover is Swarm-native and Dokploy and Coolify both speak Swarm, yet all three stay out of bucket 3. Swarm schedules containers across machines you hand-provisioned; nothing in the stack provisions the machines, replaces a dead one, or reconciles the fleet toward declared state. That missing machine lifecycle is the entire difference between "runs on several boxes" and "is a fleet."
Newer names cycling through the roundups — Ownkube, Better-PaaS, and whichever panel launches next month — slot into the same table. Run them through the test below before you compare them to anything.
The 3-question category test
Forget stars and template counts. Ask three questions about any tool and its bucket reveals itself:
- Who provisions machines? If the answer is "you rent a VPS and paste the IP into a dashboard," that is buckets 1 and 2. If the answer is "you declare machines and controllers create them," that is bucket 3.
- What schedules across them? One Docker daemon means bucket 1. Swarm means bucket 2. The Kubernetes scheduler means bucket 3.
- What happens when a node dies? In bucket 1, everything on it dies with it. In bucket 2, Swarm reschedules the containers — but stateless containers only; your database volume does not follow. In bucket 3, Kubernetes reschedules the workload and the machine controller replaces the node.
Work it on the two cases people confuse most. Add a second server to Coolify and you get two managed servers: the dashboard now deploys to either box, but no scheduler spreads one app across both, and nothing notices if one box vanishes. That is managed multi-server, not clustered — bucket 1 with a longer server list.
Join a third node to CapRover and you get genuine Swarm scheduling across three machines — but you still provisioned all three by hand, you still operate the Raft quorum yourself, and a dead manager at the wrong moment is still your outage to run. That is clustered, not a fleet — bucket 2, honestly held.
What you outgrow first in each bucket
Each bucket has a ceiling, and each ceiling arrives as a specific failure rather than a vague feeling of outgrowing something.
Bucket 1: the second machine changes nothing structural. A second twelve-dollar VPS doubles your capacity and leaves every structural problem intact: the database still lives on one disk, deploys still target boxes rather than desired state, failover is still a runbook you execute rather than a controller that fires, and no component anywhere reconciles "what is running" against "what should be running." We priced this out mechanism by mechanism in our second-machine showdown: the server is cheap, and server two never fixes the four problems that actually hurt. Coolify naming multi-server scalability as v5's core feature is the most honest signal in this space — the most popular box panel agrees the ceiling is real, and what v5 is actually building is a scheduler-shaped hole only cluster orchestration fills.
Bucket 2: the cluster is real, and so is the operations bill. Swarm gives you genuine multi-node scheduling, then hands you the quorum: real HA wants three managers, which means three machines that exist only so Raft can vote. Volumes remain the sharp edge — Swarm reschedules containers, not state, so every stateful service needs its own replication story that the panel does not provide. And the scheduler you get is the whole scheduler you will ever get: fine-grained placement, device claims, and topology awareness are Kubernetes-roadmap items, not Swarm ones. Bucket 2 is the right answer when you need containers spread across boxes without adopting Kubernetes; it is the wrong answer when you need the platform to own machine lifecycle.
The honest caveat: most apps never hit either ceiling. A single app with a small team, a backup cron job, and tolerance for a few minutes of downtime during host maintenance is genuinely well served by bucket 1 — that is the 95% case the panels are built for, and reaching past it prematurely buys operations burden, not reliability. The category error cuts both ways: comparing Dokku to a Kubernetes fleet flatters neither tool. Pick the bucket your failure modes require, not the one your ambitions prefer.
Where the Kubernetes-fleet options sit (and when you don't need them)
Bucket 3 is sparsely populated because it is genuinely harder to build: the platform must provision machines, run a control plane, and expose desired state, not just wrap a Docker socket. Porter takes the "Kubernetes inside your own cloud account" route — it stands up the cluster plus VPC, load balancer, and registry from a git connection. Kratix-style frameworks go further up the stack, treating the platform itself as Kubernetes extensions teams compose. Bex takes the owned-metal variant: Cluster API driving declarative machine lifecycle on servers you own, with a Render-compatible API so the deploy surface stays git-push-shaped while the fleet underneath is continuously reconciled toward declared state, not hand-tended box by box.
When do you need that? When your requirements include any of: workloads spread across machines by a scheduler rather than by your memory of which box has room; nodes that get replaced by controllers instead of by your runbook; or an API surface that agents — not just humans — can operate against machine-readable state. Until then, bucket 1 with good backups is not a compromise; it is the correct engineering choice, and the panels keep getting better at exactly that job every release.
Stop ranking panels against fleets
The 2026 roundups are not wrong about the tools; they are wrong about the axis. Stars measure onboarding smoothness. Template counts measure catalog breadth. Neither measures what happens at machine two, at node failure, at 3 a.m. — and those are the questions that separate a panel from a platform. Classify first with the three questions, then compare only within the bucket that matches your failure modes. Your shortlist gets shorter, your evaluation gets sharper, and you stop asking a Docker panel to be a fleet or a fleet to be as simple as a panel.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.



