Every self-hosted PaaS launches by promising a better first deploy. Deplo launched by promising a better last deploy on someone else's panel: point its installer at a VPS running Dokploy or Coolify and it reads the old panel over its own API, recreates every app, database, domain, and cron job, copies the data across, and finally takes over ports 80 and 443. Exit tooling as a headline feature is a strange way to introduce a product — unless the category's real lock-in was never the config format at all.
Here is the whole post up front. Deplo publishes a measured migration audit, dated September 4, 2026, run against live Dokploy and Coolify installations with real apps and real data — each source panel spread over two machines, the remote route landing on a third:
| Source | Apps that landed untouched | What did not |
|---|---|---|
| Dokploy | 66 of 67 | One app on a private git repository: the deploy key never leaves the old panel |
| Coolify | 60 of 62 | The same private-repository app, plus one app the token could not stop |
Two caveats before the analysis: the numbers are vendor-measured, and the feature is openly beta ("not recommended for production"). Even so, a panel that grades its own exit tooling with named misses instead of marketing copy is doing something the category rarely does — and the misses are more interesting than the hits. A deploy key that never leaves the old panel and a token that could not stop one app are not config problems. They are running-state problems. That is the thesis of this post: the moat around your single-box PaaS was never the YAML, it is the running state — and Deplo's import audit is the first document in this category to price that moat line by line.
How the takeover actually works
The mechanism has two halves, split exactly along the config/state line. Configuration — projects, apps, databases, domains, variables, volumes, crons — comes over the old panel's HTTP API with a token you paste into a seven-step wizard (choose, connect, install, review, people, take over, done). Data takes a different path: you run one shell command as root on each source machine, which installs a Deplo agent that reads the disks and streams volume contents through the control plane to the destination.
There are two routes, and the difference between them matters. Take over this server runs Deplo on the machine the old panel already occupies: the installer finds the panel, offers to bring your data over or start clean, and ends by moving ports 80 and 443 to Deplo and removing the old panel. From another server lands each app on a server you pick while the old panel keeps running untouched — the import as a trial, not a commitment.
Both routes share one sharp edge worth knowing before you start: every service you tick is stopped on the old panel when its data copy starts, and after a finished run it stays stopped. The copy is consistent because the source is frozen. A run you stop yourself is fully undone — everything created is removed, stopped services restarted — but a run that fails on its own is not rolled back, and nothing is ever deployed for you: each app waits for a human to open it, check it, and press Deploy.
The small print is refreshingly operational. On the Dokploy side, the API key must be created in the UI (Settings, Profile, API/CLI) — a key minted over the API is rate-limited to 10 requests a day, and an import needs hundreds. One run covers one source organization, so a three-org Dokploy needs three keys and three queued runs. Inbound TCP 9443 must be open on every source machine for the agent channel, and the docs insist on a snapshot of every machine first — on the takeover route, the snapshot is your only way back after the final step removes the old panel.
This is the documentation of a team that has watched migrations fail and would rather warn you than onboard you.
What comes across — and the honest inventory of what does not
The "what comes across" list is the broad one: image apps, compose apps rendered as written with named volumes, git-built apps with repo, branch, and build settings, managed databases (Postgres, MySQL, MariaDB, MongoDB, Redis, ClickHouse) with their data, bind mounts re-pointed to the destination, config file contents, shared variables, domains with path prefixes and per-domain ports, basic-auth users re-hashed on arrival, cron schedules, and backup destinations with credentials tested on landing. Inside a volume, contents, permissions, ownership, empty directories, hard links, and in-volume symlinks all survive the trip.
The other list is the one worth reading twice, because each entry names a distinct species of running state that no API export can carry:
- Secrets the old panel will not surrender. Private registry credentials and git deploy keys never come across — the report names them and you re-add them by hand. The Dokploy 66-of-67 miss lives here: the deploy key that never leaves the old panel.
- Things the destination refuses on principle. A stack reaching for the host (
privileged, host networking,cap_add, device passthrough) is rejected outright, with the offending key named. Security posture as an import filter. - Things the source API withholds. A compose file kept in a git repository is not returned by Dokploy's API at all — the app is created and the report tells you to paste the file in. Your "export" is only as complete as the other panel's API, a dependency Deplo is unusually frank about.
- State that lives outside the app model. Host cron entries, systemd units, hand-created Docker networks, files no mount points at — Deplo only knows what the app mounts. Data written outside a declared mount was already ephemeral on the old panel ("lost on the next restart, on the old panel as much as here").
- Engines with no equivalent.
libsqlon Dokploy,keydbanddragonflyon Coolify simply do not exist on the destination. The catalog gap is a migration gap.
Read as a whole, the inventory is a taxonomy of why "just re-deploy everything on the new panel" has always been a weekend-eating lie. The YAML was the easy 10%. The keys, the mounts, the schedules, the data with its permissions intact — that is the 90% Deplo automated, and the residue it lists is the residue every panel switcher has ever discovered at 2 AM.
Why a panel launches by competing on exit
Deplo's own repo tagline is "push a repo, pick a server, get a deployment," and its contributor docs state the differentiator plainly: the user must never be required to know Docker or SSH. But the install guides linked from the README tell the real go-to-market story — install, first app, migrate from Coolify, migrate from Dokploy. Two of the four doors into the product open from a competitor's hallway.
That is a rational acquisition strategy once you accept what the import inventory proves: in the single-box PaaS category, switching costs are almost entirely data gravity, not config. Nobody stays on Coolify because they love its database UI; they stay because twelve apps, three databases, and two years of uploaded files live there, and the migration is a weekend of rsync, re-pasted env vars, and re-issued certificates. A panel that automates the 90% and itemizes the residue converts "the weekend I keep postponing" into a wizard with a progress bar. Competing on exit is competing on the only switching cost that ever mattered.
There is a second-order effect worth naming. Measured coverage numbers — 66 of 67, with the miss named — are the credible form of this claim, and they put pressure on every panel that describes its own export story in adjectives. The category norm has been "import/export: partial" buried in a comparison table. Deplo's audit, re-run against live panels every release with checksums and per-file permission checks, sets a bar: if your migration story cannot survive being counted, it is not a story, it is a hope. Expect the next round of Coolify-versus-Dokploy threads to ask for numbers instead of vibes.
Where Deplo itself sits on the second-machine spectrum
Now the harder question, and the one the launch framing invites you to skip: after the takeover, what ceiling did you actually buy your way out of? The naive read — "the migration lands on one box, so nothing changed" — is wrong in an instructive way, because Deplo is not single-box software.
Its architecture is a control plane plus a small agent per server: the control plane decides (Compose files, routing rules, decrypted env), the agent executes (Docker, filesystem, shell), and the two talk over pinned mutual TLS. Servers belong to the instance, one team can use several of them, and the migration wizard itself lands each app on a server you pick. This is multi-server PaaS at the placement level.
The honest placement is one rung up from the naive read and still two rungs from a fleet. Put it on the spectrum this blog has been using all year:
| Second-machine question | Deplo | Coolify | Dokploy (Swarm) | Cluster API fleet |
|---|---|---|---|---|
| Machine joins how | Operator runs an install command per server; agent phones home | Operator registers SSH host in UI | Node joins the Swarm cluster | Declarative Machine object; controllers converge |
| App spans machines | No: each app lives on the server picked for it | No: each app lives on its host | Yes: services scheduled across nodes | Yes: scheduler + autoscaler across the fleet |
| Dead machine | Deploy fails; nothing reschedules ("never builds somewhere else instead") | Same: the app is down with its host | Swarm reschedules stateless replicas | Controllers reschedule and reprovision |
| Shared edge | One Traefik per server, ports 80/443 each | One proxy per host | Traefik routing across the Swarm | Shared ingress + external LB, declarative |
| Provisioning model | Imperative per-server enrollment | Imperative per-host registration | Cluster membership | Desired-state reconciliation |
Judge it against the two criteria that define the ceiling. Declarative provisioning? No — every server enters Deplo through an operator running a command, the same enrollment-shaped onboarding as Coolify's remotes, with no machine lifecycle the platform reconciles toward. Fleet lifecycle? No — placement is per app, there is no cross-server scheduling or rescheduling, the edge is per server, and upgrades are a per-server affair. Deplo's second-machine story is Coolify's islands model with a cleaner control plane and a certificate-pinned agent instead of SSH — genuinely better ergonomics, the same architectural rung.
That is not a dismissal. "Many servers, one control plane, per-app placement" covers an enormous territory: the agency with thirty client sites, the team whose staging and prod should stop sharing a disk, anyone whose growth plan is more small things rather than one big thing that must survive a dead box. But the takeover moves your running state between panels; it does not move the ceiling. The declarative half of the spectrum — machines as reconciled objects, scheduling as a platform answer rather than an operator decision — is exactly where the migration leaves it, which is to say untouched.
Who should take the takeover
The decision practically writes itself once the two halves are separated. Take the takeover — same-server route, snapshot first — if your complaint is with the panel: the UI fights you, the update cadence worries you, the SSH-and-shell tax on every change has come due, and Deplo's never-touch-Docker-or-SSH pitch reads like relief. The measured audit says the move itself is a bounded weekend with a named residue, not an open-ended migration project, and the from-another-server route lets you rehearse it with the old panel still standing.
Stay put — or rather, recognize that no panel switch answers your question — if your complaint is with the ceiling: you need an app to survive its machine, placement decisions you stop making by hand, or provisioning that survives the operator going on holiday. That is the declarative-provisioning, fleet-lifecycle half of the table, and moving running state from one per-app-placement panel to another leaves every cell of it unchanged. The migration wizard is superb at answering "how do I leave"; it cannot answer "where does this architecture stop," because the answer is the same on both sides of the move.
Deplo deserves credit for the document it published as much as the tool it shipped. The September 4 audit — two source panels, two machines each, a third machine catching the remote landings, every miss named — is the first honest pricing of single-box lock-in this category has produced: the YAML was never the moat, the running state was, and here is the count. Just read the receipt all the way down. It prices the move between panels. The move past panels is a different receipt entirely.
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.



