Migrations

Beta

Move an existing Dokploy or Coolify installation, or another Deplo, to Deplo, data included.

Beta

This feature is currently beta/experimental and subject to change. It is not recommended for production. Try it out and share your feedback on our GitHub.

Deplo reads an existing Dokploy or Coolify installation through its API and recreates it here: projects, apps, databases, domains, variables and volumes, with the data copied across. It does not need SSH into the old panel, and it never deletes anything on the source.

It reads another Deplo the same way, one team at a time.

Two routes

Take over this serverFrom another server
Where Deplo runsThe machine the old panel already runs onA machine of your own
How you start itThe installer finds the panel and asksSettings -> System -> Migrations
Who can run itWhoever installs DeploAn instance admin
Where apps landThis machineA server you pick, per app
Ports 80 and 443Deplo takes them at the endUntouched
The old panel afterwardsRemoved from the machineStill running, still yours

Both routes use the same wizard. The takeover adds one step at the start (bring data over or start clean) and one at the end (move the ports). Moving from another Deplo always takes the second route.

On both routes a Deplo agent on the source machine reads the volumes. The data passes through the control plane, also when source and destination are the same machine. From another Deplo nothing is installed: the old Deplo hands its volumes over itself.

The wizard

Seven steps. A step opens only when the one before it is finished.

StepWhat it asks for
ChooseTakeover only. Bring your data over, or start clean.
ConnectThe panel's address and a token, one per source team.
InstallOne shell command to run on each source machine. Skipped for another Deplo.
ReviewWhat comes over, where each item lands, then Start migration.
PeopleInstance admins only. Single-use registration links for the panel's members.
Take overTakeover only. The confirmation that moves ports 80 and 443.
DoneThe report.

After Start migration the review is locked until the run ends. A takeover with Start clean skips the middle steps and goes straight to Take over and Done.

What comes across

ShapeNotes
An app from a Docker imageImage, tag, command, environment, ports.
An app from a compose fileRendered as written, with its named volumes.
An app built from a git repositoryRepository, branch, build settings.
Managed databasesPostgres, MySQL, MariaDB, MongoDB, Redis and ClickHouse, with their data.
Named volumesIncluding deep trees, empty directories and zero-byte files.
Bind mounts of a host directoryCopied to the destination and re-pointed.
Bind mounts of a single fileCopied with its contents.
Config filesThe file contents travel, not only the mount path.
A volume shared between services of one stackCopied once, mounted where it was.
Environment variablesPer app and shared, with their values.
Domains and routesIncluding a path prefix and a per-domain port.
Basic authUsers and passwords, re-hashed on arrival.
Cron jobsSchedule and command.
Backup destinations and schedulesThe store's credentials, tested on arrival.
Preview-only variablesAs the app's own preview variables here.

Inside a volume, file contents, permissions, ownership, empty directories, zero-byte files, unicode and long paths, hard links and symbolic links inside the same volume are all preserved.

What needs a look

These are not failures. Deplo brings across what it can and lists the rest in the report.

ShapeWhat happens
A stack that reaches the hostprivileged, network_mode: host, cap_add, device passthrough. For security reasons Deplo refuses it and says which key stopped it.
An image from a private registryThe image reference comes across, the credentials do not. The report names the registry so you can add it.
A compose file kept in a git repositoryDokploy does not return it over its API. The app is created and the report tells you to paste the file in.
Device nodes, sockets and named pipes in a volumeNot copied. Each one is listed with its path.
Symbolic links pointing outside their volumeNot copied. Listed with its path.
State that lives outside the appA cron entry on the host, a systemd unit, a file no mount points at. Deplo only knows what the app mounts.
Data written outside a declared mountIt is lost on the next restart, on the old panel as much as here.
A very large volume onto a small diskDeplo checks the destination's free space first and warns before it starts.

What does not come across

  • Private registry credentials.
  • Git deploy keys and connected-source credentials. Add a git connection here instead.
  • Device nodes, sockets and named pipes inside a volume.
  • Symbolic links that leave their own volume.
  • Host files such as /etc/localtime and /etc/resolv.conf.
  • Networks you created by hand on the source machine.
  • Engines that do not exist here: libsql on Dokploy, keydb and dragonfly on Coolify.

Stopping, data, and going back

Read this before you start.

  • Every service you tick is stopped on the old panel when its data copy starts. This keeps the copy consistent.
  • On a run that finishes, it stays stopped. Deplo starts it again only when you stop the run during the data step, or cancel a takeover.
  • The source is only read. Nothing on the old panel is deleted, except by the takeover's own final confirmation.
  • The destination is emptied before it is written. A second run does not merge two copies.
  • Stop undoes the whole run, in any step. Everything created here is removed with its data, and the stopped services are started again on the old panel.
  • A run that fails on its own is not rolled back. What is already here stays. A service whose data did not arrive refuses to deploy until you copy the data again or press Deploy anyway.
  • Nothing is deployed for you. Open each app, check it, and press Deploy.

How this is tested

Every release, migrations run against a live Dokploy and a live Coolify installation with real apps and real data. Each app is checked before and after the move: data records, HTTP responses, database counts and checksums, and every file in every volume with its permissions and owner. The same tests also run behind a firewall, behind a CDN, with a source machine going offline during the run, onto a nearly full disk, and on a busy instance with several teams.

Measured on 4 September 2026, each panel spread over two machines, the remote route landing on a third.

SourceRouteApps that landed untouchedWhat did not
DokployBoth66 of 67One app on a private git repository: the deploy key never leaves the old panel, and the report names it.
CoolifyBoth60 of 62The same private repository, plus one app the token could not stop.

Next steps

Did this page help you?

On this page