On August 16, 2026, a platform-research commit labeled TLM-1090 scored six self-hosted deployment tools for a Hetzner deployment — Coolify v4, Dokploy, CapRover, Kamal 2, Dokku, and Portainer BE — against exactly two criteria: a multi-service future and low ops burden. The top two were Coolify v4 and Dokploy. Everything else fell out, and the reasons it fell out are more interesting than the winners.
That is the whole verdict, delivered in the first paragraph the way the decision doc deserves. What follows is the reconstruction: why those two survived, what a real selection matrix rewards that feature-comparison posts never measure, and the question the doc deferred — where the same "low ops burden" criterion points once the team outgrows one box. One honesty note first: the upstream repo holding the original research is currently unreachable, so the matrix below is rebuilt from the doc's recorded criteria and verdict, with every tool's current state verified independently against 2026 sources.
The six-way matrix, reconstructed
Feature-matrix blog posts compare capability breadth: who has more one-click apps, more build providers, more checkboxes. A real decision matrix for a team about to bet its production deploys on a tool asks narrower, harsher questions. Rebuilt against the doc's two criteria, the elimination round looks like this:
| Tool (2026 state) | Git-push PaaS flow? | Preview deploys? | Multi-service story | Ops burden | Verdict |
|---|---|---|---|---|---|
| Coolify v4.0.0+ (Apr 2026, ~55k stars) | Yes, with UI + API | Yes | Multi-server over SSH, Swarm experimental | Medium: heavier idle, dashboard must be firewalled | Finalist |
| Dokploy v0.29.x (~34k stars) | Yes, close to native Compose | Yes | Native Swarm, non-root multi-server since v0.29.0 | Low: 300–400 MB idle, standard Compose | Finalist |
| CapRover v1.14.2 (May 2026) | Yes | No | Swarm clustering, fragile beyond a few nodes | Low, but stagnant surface | Out: no previews, aging UX |
| Kamal 2 (Rails 8 default) | No — CLI deploys from your laptop | No | One deploy config per app, no fleet view | Low per app, linear per service | Out: intentionally not a PaaS |
| Dokku (CLI-first) | Yes, git-remote style | No | Single-node primary | Low, but single-box ceiling | Out: no previews, single node |
| Portainer BE | No — manages Docker, doesn't deploy from git | No | Excellent container fleet view | Low for ops, but it's not a deploy path | Out: no git-push flow |
The pattern in the "Out" column is the entire lesson. Nobody got eliminated for missing a feature-checkbox. CapRover and Dokku fell out over preview deploys — the single workflow that separates "runs my app" from "runs my team's process."
Kamal lost not because it is bad (it is excellent at what it does) but because it is deliberately not a PaaS: no dashboard, no shared control plane, one deploy.yml per app. Portainer manages Docker beautifully and deploys from git not at all. The matrix rewarded operability over capability breadth: the shape of the daily workflow, not the length of the feature list.
Why the two finalists survived
Coolify and Dokploy look interchangeable from a landing page — one-command install, Git deploys, automatic TLS through Traefik, a web UI over Docker. The 2026 head-to-head numbers tell a more textured story:
| Axis (2026) | Coolify v4 | Dokploy v0.29.x |
|---|---|---|
| License | Apache 2.0, everything, no paid tier in self-hosted | Apache 2.0 core; Source Available license gates future enterprise features (SSO, RBAC, audit logs) since Jan 2026 |
| Idle footprint | 500 MB–1.2 GB RAM depending on monitoring config | 300–400 MB RAM, under 2% CPU at rest |
| Compose zero-downtime | Not supported — Compose deploys stop all containers first; rolling updates only via Dockerfile/Nixpacks/image, Compose support roadmapped for v5 | Standard Compose handling; stop/start doesn't trigger a rebuild |
| Multi-server | SSH-attached remotes plus shared registry; Swarm labeled experimental, minimum three same-arch servers | Swarm is a first-class mode; non-root multi-server support landed in v0.29.0 |
| One-click catalog | 300+ service templates, the largest library | Smaller, uncounted in docs |
| Build inputs | Nixpacks, Dockerfile, image | Nixpacks, Dockerfile, image, plus Heroku, Paketo, and Railpack buildpacks |
| January 2026 event | 11 CVEs disclosed, patched in v4.0.0 — update discipline + dashboard exposure became the ops story | License restructure: core to standard Apache 2.0, paid tier defined and fenced |
Read that table through the doc's two criteria and the verdict writes itself. On low ops burden, Dokploy's standard Compose handling is the standout: a docker-compose.yml that runs on a laptop deploys with little to no modification, while Coolify's "magic variables" injection sometimes demands adjustments. A container restart on Coolify can even trigger a full rebuild where Dokploy just restarts.
On multi-service future, both clear the bar the other four missed — preview environments, a shared control plane, a path (however narrow) past one server. Dokploy's native Swarm versus Coolify's experimental Swarm is the one near-term differentiator, and only if clustering is quarters, not years, away.
Coolify's counterweight is ecosystem gravity: roughly 55k stars to Dokploy's 34k, a 300+ template catalog that settles "deploy n8n and Supabase by lunch" without writing Compose at all, ARM64 support Dokploy doesn't advertise, and a pure Apache 2.0 posture with no future paid tier waiting. That last point lands the moment a team needs SSO or audit logs and discovers Dokploy has fenced those for its Startup tier and above.
The January CVE disclosure cuts the other way and deserves its weight: eleven critical flaws patched in v4.0.0 is a yellow flag on update discipline and dashboard exposure (bind it to a private network, never the public internet), not a project disqualifier.
Neither finalist won on every axis. That is precisely what makes this a real decision instead of a roundup: the doc picked the two tools whose weaknesses the team could live with, not the two with the longest feature lists.
What real matrices reward that feature tables don't
Distill the elimination round and the final, and four operability criteria emerge that almost never appear in "top 10 self-hosted Heroku alternatives" posts:
1. Preview deploys as a process gate. CapRover and Dokku don't lack features in general; they lack per-PR environments specifically. For a team, that one gap vetoes the tool, because review workflows route through deploy previews. Individuals self-hosting side projects never feel this; teams feel it on week one.
2. Restart cost, not just deploy cost. Feature tables measure the happy path: push, build, live. Operators live on the sad path: a stuck container at 2 AM. Dokploy restarts the container; Coolify rebuilds it. On a small Hetzner VPS where a rebuild storm eats the whole CPU budget, that behavioral difference is a sizing decision disguised as a UX detail.
3. Compose fidelity. Both finalists accept a docker-compose.yml, but "accepts" covers a spectrum from Dokploy's near-native handling to Coolify's rewrite-and-inject layer. A real matrix tests the team's actual Compose stack, not a hello-world, because the migration tax is proportional to how much the platform massages standard files.
4. Exposure discipline as a shipped cost. The team that picks Coolify inherits a concrete ops task from day one: firewall the dashboard, keep updates current, treat port 8000 like SSH. That's not an argument against Coolify — it's an argument for pricing it into "low ops burden" honestly instead of discovering it from an incident.
Notice what none of these criteria mention: one-click catalog size, star counts, or which buildpacks are supported. Those decide ties. Operability decides eliminations.
The machine-two question the doc deferred
Here is the seam the decision doc correctly scoped out but every reader should scope back in: neither finalist provisions machines. Both tools answer "run my services on servers I have." Neither answers "give me servers." The day the team needs a second Hetzner box, the low-ops-burden winner hands them this checklist:
- Rent and harden the box yourself — OS, SSH, firewall, Docker, disk layout.
- Attach it over SSH (Coolify's standard pattern) or join it to Swarm (Dokploy's native path; Coolify's experimental one, three same-arch nodes minimum for quorum).
- Stand up the shared Docker registry both multi-server patterns assume.
- Reason about Traefik-per-server routing, volume locality for stateful services, and what happens to in-flight requests when a Compose deploy stops containers across hosts.
- Invent your own node health story: nothing here does MachineHealthCheck-style remediation or autoscaling.
That list is not an indictment — single-box tools that pretend the second box is trivial would be worse. But it reframes the verdict: the doc optimized for the team's current shape (few services, one server, small ops budget) and the winner's margin evaporates exactly at the growth event the "multi-service future" criterion was gesturing toward. A 2026 hands-on comparison put it bluntly in matrix form: Coolify "limited, single-node primary," Dokploy leaning on Swarm, CapRover's Swarm "fragile beyond a few nodes." Swarm is a fine answer for two to five boxes and a cliff edge past that — no declarative machine lifecycle, no reconciliation loop that notices a dead node and replaces it, no API an agent can call to grow the fleet.
This is the exact seam a Cluster API-based platform is built to not have. The moment "add a machine" should be a declarative act — a manifest change reconciled by controllers, with health checks, rollout policy, and autoscaling — rather than a weekend of SSH, the evaluation criteria flip: the thing being scored is no longer the deploy dashboard but the machine lifecycle underneath it. The doc's "low ops burden" criterion, applied honestly at machine two, points away from every tool on its own shortlist and toward a platform where nodes are cattle the system herds, not pets the team SSHs into. Keep the PaaS UX the team already chose; put it on a substrate where the second server — and the twentieth — arrives by reconciliation, not by runbook.
The takeaway for your own shortlist
Borrow the doc's structure the next time you evaluate self-hosted platforms: two criteria, scored against your actual workflow, with elimination reasons written down. You will likely find what TLM-1090 found — that preview environments, restart behavior, Compose fidelity, and exposure discipline eliminate faster than any feature table, and that the winner earns its place by having livable weaknesses rather than maximal checkboxes. And write down the deferred question too: what your pick does at machine two. The honest answer shapes your architecture a year before you need it.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with declarative infrastructure underneath so machine two arrives by reconciliation instead of runbook. Star the repo on GitHub or deploy your first app today.



