Skip to main content

Canine vs Coolify vs Dokploy: What the awesome-paas List Doesn't Tell You About the Second Machine

9 min readDora NodaDora Noda
Share
On this page

The awesome-paas list puts roughly forty self-hosted PaaS options side by side in one flat alphabetical section, each entry an identical one-line link. Coolify's 62,000 stars and a project untouched in years get exactly the same typography. Nothing on the page tells you which entries survive the day you need a second machine — and that day is the only test that matters, because every demo ends on one server and your second year doesn't.

Read past the list's flat surface and the forty entries collapse into three architectures with three different second-machine fates. Here is the verdict table first; the evidence follows.

ArchitectureList examplesSecond-machine fate
Single-box DockerDokku, PikuNo story — you migrate, not scale
Multi-server / Swarm DockerCoolify (~62k stars), Dokploy (~37k stars), CapRover (~15k stars)A story, but you provision the box and place the workload by hand
Attach-to-your-KubernetesCanine (~2.9k stars), Kubero (~4.4k stars), Porter, OtomiInherits scheduling from K8s — but you still bring (and grow) the cluster

Three worked examples below — Canine, Coolify, Dokploy — show what each fate concretely means. The punchline up front: all three assume the machines already exist. None of them provisions machine two; they only disagree about what happens after you've racked it yourself.

What the list actually contains​

Two corrections before the comparison, because the file on disk differs from how it's usually described. First, the list has no status badges, freshness tags, or activity signals of any kind — it's a plain curated link list in alphabetical order, last-touched at the curator's pace. Gatsby Cloud still sits in the Jamstack section years after Netlify shut it down, and the PaaS section still links dotCloud with a note that it became Docker Inc back in 2013. "On the list" means "someone added the link once," not "this project is alive."

Second, the Kubernetes-native bench is thinner than the category's marketing suggests. The self-hosted section does include Canine, Kubero, and Porter alongside the Docker crowd — but Deckrun, often named in the same breath, isn't on the list at all. The K8s-attach entries are also outnumbered several times over by Docker-based tools and dormant history — Flynn, archived on GitHub since 2021, still holds its alphabetical slot between Dokploy and Hatchbox. A reader picking by list position or star count will land on a Docker-box tool every time. That's not wrong — it's just a choice the list never announces it's making for you.

With that framing set, here are the three second-machine plays, worked concretely.

The three second-machine plays​

Coolify: attach another server, keep placing workloads by hand​

Coolify's multi-server model is the most literal of the three. One Coolify instance acts as the dashboard; you register additional servers over SSH in the Servers tab, Coolify installs Docker on them, and from then on each app or database targets a specific server that you choose. There is no scheduler deciding placement — you do, per workload. The recommended topology in Coolify's own README says it plainly: one server for Coolify, one or more servers for deployed resources. A dedicated remote build server option keeps compiles from stealing CPU from production.

The ceiling is architectural, not a missing feature. The Coolify host is a single control-plane point of failure: lose the dashboard server and deploys, TLS renewals, and scheduled backups stop until it's restored. Docker Swarm as a deploy destination exists but is experimental, and the v5 rewrite is moving away from the v4 approach — so a Swarm topology on Coolify foundations is a bet against the project's own direction. Server two joins in minutes; it just never becomes part of a cluster, because there is no cluster. Every box stays a pet you placed by hand.

Dokploy: SSH remotes, or join real Swarm workers​

Dokploy gives you Coolify's model and one step more. Like Coolify, it supports independent remote servers over SSH — a common setup is a small box running only the Dokploy UI with apps deployed to remotes, and the v0.29.0 release closed a real gap by allowing non-root users with passwordless sudo instead of root-only SSH. Unlike Coolify, Dokploy also ships Docker Swarm as a first-class, non-experimental mode: join a worker with docker swarm join, and Traefik routes across nodes with automatic HTTPS in both single-server and Swarm setups.

Dokploy's own docs draw the line honestly: use Swarm nodes only when you need the same application replicated across multiple machines with load balancing. That sentence is the whole test in miniature — Swarm gets you replica scheduling for stateless apps, but the cluster still starts from machines you provisioned, joined, and maintain yourself, with the Dokploy manager as the box you can't lose. It's the furthest the Docker-native architecture goes, and the docs don't pretend it goes further.

Canine: inherit the scheduler, bring your own cluster​

Canine is the list's representative of the third architecture: a Heroku-style git-push PaaS that runs on a Kubernetes cluster you already have. Connect a repo, it builds the image and lands it on your cluster as a Deployment, Service, and Ingress — with multi-cluster management from one UI. The second machine, in this world, is a node you add to your cluster (or that your cluster autoscaler adds for you), and the scheduler places work on it without anyone clicking a per-server dropdown. Scheduling, rescheduling after failure, and replica spreading come with the orchestrator instead of being features the PaaS has to reinvent.

The honest caveats cut the other way from the Docker tools'. Canine is young — roughly 2,900 stars against Coolify's 62,000 — and it attaches to a cluster rather than creating one, so "add a node" is still your problem (or your autoscaler's). It's a Rails app talking to the Kubernetes API, not an operator with its own CRDs, and it's sponsored by Portainer with paid support as the business model — worth knowing before betting production on it. And one detail worth checking yourself rather than repeating from the landing page: the marketing site calls the self-hosted edition "MIT licensed" while the repo's LICENSE file is Apache 2.0. Permissive either way — but the discrepancy is exactly the kind of thing a flat link list can't show you.

The layer none of them owns​

Stack the three plays and the shared gap is obvious: Coolify attaches machines, Dokploy joins machines, Canine borrows a cluster made of machines — and in all three cases you are the machine layer. Somebody rents the VPS, installs the OS, joins it to the right thing, replaces the disk when SMART errors start, and repeats it all when the box dies at 3 a.m. The list's forty entries differ in what they do with servers; none of them answers "where do servers come from."

That unowned layer has a name in the Kubernetes world: declarative machine lifecycle, the thing Cluster API exists to provide. The shape of it is a manifest that says "this fleet has N machines of this shape" with controllers that reconcile reality to match — failed nodes replaced, upgrades rolled, drift corrected — instead of an operator SSHing into boxes. SNCF's national-rail CAPI fleet, reconciled monthly to zero drift, is the enterprise proof that the loop works; a Hetzner-backed fleet running a handful of machines is the same loop with lower stakes. This isn't a pitch for any particular tool so much as a lens: when you evaluate a list entry, ask which side of the machine line it sits on. Everything above the line is UX. The line itself is the ops burden you'll still be carrying in year two.

How to read the list​

If the list won't sort itself, sort it yourself with one question per entry: what happens on machine two, and who provisions it? The answers cluster cleanly:

  • Solo dev, one app, maybe forever one box: the single-box tools (Dokku and its descendants) are the honest pick — if you outgrow them, you wanted a different architecture anyway, not a bigger version of the same one.
  • Small team, a few apps, growth likely: Coolify's SSH remotes or Dokploy's remotes-plus-Swarm cover the "three to five boxes placed by hand" era well. Pick Dokploy if replicated-across-machines matters soon; the Swarm mode is real today, not a roadmap slide.
  • Growing team with Kubernetes already (or willing to learn it): the attach-to-K8s entries — Canine, Kubero, Porter — inherit scheduling, self-healing, and autoscaling from the orchestrator. The price is the cluster itself: somebody still builds and feeds it.
  • Nobody on this list: provisions the machines. If "a box died and nobody paged anyone because a controller replaced it" is the requirement, you're shopping for a fleet layer above every entry here, not a better entry.

One more filter before you click anything: check the repo's pulse, not the list's inclusion. A pushed date, an open-issue curve, and a license file you read yourself beat forty alphabetical links every time. The list is a starting point for a search, not the search.

Lists go stale; architectures don't​

The awesome-paas list will keep growing — new entries appended, dead ones lingering, all of it in identical type. That's what curator lists do. The useful skill isn't finding the list; it's seeing through it to the three architectures underneath and picking the second-machine fate you can live with: migrate later, place by hand, or inherit a scheduler and feed the cluster.

And if even the best of those fates sounds like ops work you'd rather not do by hand — a repo that becomes a running HTTPS service on machines the platform itself provisions, reconciles, and replaces — that's the layer this whole comparison points at from below.

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.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex