Your Coolify box is doing fine. Then a post goes semi-viral, the build queue backs up because Docker builds are eating the same CPU your app needs to serve traffic, and you decide it's time for server #2. You click "Add Server." What happens next is the entire subject of this post — and it's less than the phrase implies.
Both Coolify and Dokploy shipped real multi-server capability in 2026 — Dokploy added Docker Swarm-based multi-node support, and Coolify's server-connection feature moved out of pure novelty. 2026 comparison roundups now frame Dokploy as the simpler pick for a solo developer's first deploy and Coolify as the more capable option once a team is involved. Both framings are true and both undersell the same fact: neither tool provisions a second server. They connect to one you already stood up by hand, and from there almost everything is still your job.
What "Add Server" Actually Does
Here's the mechanism in both tools, and what a Cluster API-managed fleet does instead for the same request.
| Coolify | Dokploy | Cluster API (CAPH example) | |
|---|---|---|---|
| How you add capacity | Generate an SSH key in the dashboard, copy it to ~/.ssh/authorized_keys on a server you already created, validate the connection | Convert your setup to Docker Swarm; add worker nodes from the dashboard, but the node itself must already exist and be reachable | Bump a MachineDeployment replica count; a controller creates the actual machine |
| Who creates the underlying VM/box | You, in the Hetzner/AWS console, by hand | You, in the Hetzner/AWS console, by hand | The controller, via the cloud/bare-metal provider's API |
| Cross-server networking | Requires a shared Docker Registry so images can be pulled on each node | Native — Swarm's overlay network handles it, but you're now running Swarm, not standalone Docker | Native — cluster networking (CNI) is standard across every node the controller adds |
| Load balancing across new nodes | Explicitly manual — Coolify's own docs state load balancer setup "is not automated" | Swarm's routing mesh handles intra-cluster traffic, but nothing configures an external LB for you | A Service/Ingress object picks up new nodes automatically as they join |
| Status as of 2026 | "Experimental feature," per Coolify's docs | Requires committing to Swarm cluster semantics, not "add a disparate box for a different app" (that request sat open as Dokploy issue #139 until it shipped in v1.0) | Stable, in production at fleets like SNCF's 200+-cluster deployment |
Notice the pattern in the middle two columns: in both PaaS tools, you are the provisioning layer. The dashboard button is a connector, not a controller. Cluster API's contribution isn't a nicer dashboard — it's that "add a machine" is a declarative object a controller reconciles, instead of an imperative sequence of steps a human runs once and then forgets to repeat consistently.
Three Moments Where the Gap Actually Bites
The table above is the mechanism. Here's where it costs you something real.
A node dies at 3 a.m. On Coolify or Dokploy, a dead server means SSH access is gone, deployments to that node fail silently or queue up, and someone gets paged to either revive the box or manually remove it from the server list and reconfigure whatever was running there. There's no controller watching server health and no automatic remediation — you are the remediation. Cluster API's bare-metal provider (CAPH, the Hetzner implementation) ships a HetznerBareMetalRemediationController that reconciles a failed HetznerBareMetalMachine by triggering the requested remediation type — reboot, reimage, or full re-provision — without a human in the loop. This is one CAPI provider's implementation, not a universal property of every Cluster API infrastructure provider, but it's exactly the category of automation that "SSH back in" can't replicate at 3 a.m.
Traffic burst, you need three more nodes by Friday. On Coolify or Dokploy, that's: open the Hetzner console, provision three VMs, generate or reuse an SSH key, paste it onto each box, add each one in the dashboard individually, and — for Coolify — hand-configure the load balancer to know about them. On a Cluster API fleet, it's a MachineDeployment.spec.replicas edit from 5 to 8; the controller calls the provider's API, boots the machines, joins them to the cluster, and a Service already routes to whatever matches its label selector. Same outcome, one is a change request, the other is an afternoon of manual server setup per node.
A new server needs to serve traffic, not just exist. Coolify's docs are blunt that load balancer wiring "is not automated" — you're expected to stand up your own reverse proxy or LB and keep its target list in sync with whatever nodes you've added. Dokploy's Swarm mode gets you intra-cluster routing via Swarm's mesh, but that's a different guarantee than "new capacity is automatically part of what serves external traffic," which is what a Kubernetes Service gives you for free the moment a node joins.
What the Same Reconciliation Loop Looks Like at 200 Clusters
It's worth seeing what the "controller instead of a human" model looks like once it's stretched far past a two- or three-server setup, because it's the same mechanism, just at a scale neither Coolify nor Dokploy is built to reach. SNCF — France's national railway operator — rebuilt its platform around Cluster API to run roughly 200 Kubernetes clusters across AWS, Azure, and its own datacenters as one reconciled fleet, according to a CNCF case study and a companion Sidero Labs write-up. Two numbers stand out: clusters that used to require manual, bespoke setup now provision in about 30 minutes, and updates roll out on a monthly cadence with what SNCF describes as zero configuration drift — because the controller is continuously reconciling live state against the declared spec, not applying a script once and hoping nothing changes underneath it.
SNCF's scale is not the point of comparison for a team choosing between Coolify and Dokploy — nobody adding a second Hetzner box needs 200 clusters. The point is what the same reconciliation loop buys at any scale above one: SNCF didn't write custom automation to prevent drift across 200 clusters, it got that property from adopting Cluster API's model, the identical model a CAPH-based fleet gets on two nodes or twenty. Coolify and Dokploy have no equivalent primitive to inherit that property from, at any scale — their multi-server features are still the SSH-connect-and-hope model, just repeated more times.
When This Gap Doesn't Matter — and When It Does
None of this makes Coolify or Dokploy the wrong choice for most of the people running them. A solo developer or small team on one or two boxes, scaling rarely and manually, is well served by either — standing up a Kubernetes control plane and a Cluster API provider to manage a single VPS is genuine overkill, and both tools are honest that "experimental" multi-server support is a bonus, not the core pitch.
Run the numbers on where that overkill claim stops holding. A single Hetzner CX-class VM runs roughly $5–$15/month, and Coolify or Dokploy's SSH-connect model costs you nothing extra to add a second one at that size — the "control plane" is the dashboard you already have. A minimal CAPI/CAPH setup, by contrast, needs a management cluster (even a small one is another $10–$30/month VM) plus the operational overhead of running Cluster API's own controllers, which is real cost for a team that only ever needs two boxes. That overhead stops being a tax and starts being the cheaper option the moment you're provisioning or replacing nodes often enough that the manual steps — SSH keys, console clicks, load-balancer edits — become a recurring weekly task instead of a once-a-quarter chore. At that frequency, the engineer-hours spent babysitting servers by hand outweigh the cost of a management cluster doing it for free in the background.
The crossover point is specific: you need it once you have more than one server and you want scaling or failure recovery that doesn't route through a human doing steps in a console at 2 a.m. That's a smaller set of teams than "everyone who outgrows a single box," but it's not a rare one either — it's exactly the point where "manage the box you already have" and "own a fleet that provisions and heals itself" stop being the same problem with a different UI skin.
The Gap Is Structural, Not a Missing Checkbox
It's tempting to read Coolify's "experimental" label or Dokploy's once-open feature request and assume declarative, self-healing multi-machine support is coming — just not shipped yet. That's the wrong read. Both tools are architected around a single Docker daemon (or a Swarm cluster you opt into) that a dashboard talks to over SSH. Retrofitting "the controller provisions the box" onto that model isn't a feature PR; it's a different control plane, which is what Cluster API actually is.
That's also why bex is built on Cluster API Provider Hetzner from the start rather than adding fleet management as a later feature: a MachineDeployment and a remediation controller aren't bolted onto a git-push deploy flow, they're what the deploy flow runs on top of. Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with the same Cluster API machinery handling node provisioning and recovery underneath. Star the repo on GitHub or deploy your first app today.
The honest advice for anyone evaluating Coolify against Dokploy in 2026 is to keep doing it — they're solving "manage the box I have" well, and that's most people's actual problem. The question worth asking before you commit is whether your actual problem, six months out, is going to be a fleet — because that's the one neither tool's roadmap is going to solve for you.



