Move from Dokploy

Beta

Read a Dokploy installation over its API and recreate it in 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.

A wizard reads your Dokploy installation over its API and recreates it here: projects, apps, domains, variables, volumes and databases, with the data copied across. The configuration comes from the API. The data is read by a Deplo agent installed on each Dokploy machine.

Pick the tab that matches where Deplo will run: on the machine Dokploy already runs on, or on a machine of your own.

Before you start

Create the API key

In Dokploy: Settings, Profile, API/CLI. Create the key from that dialog, not through Dokploy's API. A key created over the API has a limit of 10 requests a day, and an import needs hundreds. It would stop part-way with a 401 error. Raise or disable the limit in the same place.

One run per source organization

A Dokploy key only reads one organization. If your Dokploy has three, create a key for each. Paste the next one, press Add, and it joins the Teams to bring over list with the Deplo team it lands in. Two organizations may land in the same team, or each in its own.

Each organization is one run. The runs are queued on the server and done one after another, so you can close the page and come back later.

On every source machine

  • One shell command, as root, on each machine. It installs the Deplo agent that reads the disks. It works behind any firewall.
  • Inbound TCP 9443 on each machine. Deplo connects back to read the volumes.
  • A snapshot of every machine, taken first. It is the only way back.
  • Free space on the destination disk. Deplo warns under 10% free or under 5 GiB.

What the run stops

Every service you tick is stopped on Dokploy when its data copy starts. After a finished run it is not started again. Anything you leave unticked is not touched.

Run the migration

Snapshot the server. The final step removes Dokploy. The snapshot is your only way back after that.

Run the installer. The same command as any other install:

curl -fsSL https://deplo.build/install.sh | bash

It finds Dokploy and asks whether Deplo may replace it. Answer no and nothing is installed. --yes does not answer this question. To skip it, set DEPLO_TAKEOVER=dokploy.

Open the address it prints. Until the ports move, Deplo answers over plain http on port 80. After the takeover the same address answers over https. If the installer says Dokploy has no dynamic config directory, use a tunnel instead: ssh -L 3001:localhost:3001 [email protected].

Create your account, then choose. The first step of the wizard asks the one question that cannot be undone: Bring your data over, or Start clean. Start clean deletes Dokploy and everything it runs, and goes straight to Take over.

Connect, Install, Review. The panel is already filled in. Paste an API key per Dokploy organization, run the printed command on any other machine behind the panel, tick what comes over, and press Start migration. Everything lands on this machine.

Take over the machine. This step opens once every organization on the list has landed. Tick I have no other teams on this panel, tick again for any service whose data copy failed, and type dokploy to confirm.

Deplo then stops Dokploy and its apps, copies its certificates, moves Traefik onto ports 80 and 443, removes Dokploy's containers, networks, images and directory, and restarts Docker. Volumes and Dokploy's own backups stay on the disk.

The page moves to the https address by itself once the certificate is issued.

Deploy your apps. Nothing is deployed for you. Open each app, check it, and press Deploy.

What comes across

What lands as what

On DokployHere
Application built with nixpacks, a Dockerfile or as a static siteApp built from its git repository
Application from a Docker imageApp running that image
Compose serviceCompose stack
PostgreSQL, MySQL, MariaDB, MongoDB, RedisThe same database engine
LibSQLNothing. Named in the report
Volumes and directory mountsVolume, with its data
File mountsConfig file under Storage
Environment variablesThe app's variables, every one plain
Preview-only variablesThe app's preview variables
Project and environment variablesShared variables, linked to the apps that referenced them
Domains, with their port and pathDomains
HTTP basic authAccess
Memory and CPU limitsResources
Health checkAdvanced -> Health check
Published host portsAdvanced -> Published ports, with the publish-ports permission
SchedulesCron jobs
S3 destinationsBackup destinations, tested on arrival
Scheduled database backups to S3Backup schedules, on the destination that came with them
Volume backupsApp backups, one per schedule, covering every volume of the app

What changes on the way

  • Temporary hostnames get a new address. A name on traefik.me, sslip.io, deplo.site or localhost contains the old server's IP, so Deplo generates a new deplo.site address. The app's Domains section shows which became which. Domains you own come across as they are.
  • Connection strings are rewritten. A database answers as db-<name> here, and every variable that used the old hostname is updated. Values an app stores by itself (a saved trusted_domains or siteurl) are not changed. Fix them from the app's Console.
  • A published host port comes across and needs the publish-ports permission. Without it the app still arrives, and the report names the ports it left behind. A port under 1024 cannot be published again; use a domain instead.
  • A middleware label in a compose file comes across when its kind is supported. Router labels never do. See Middlewares in a compose file.
  • Security headers stay off on a moved app's domains. The app answered without them before, so nothing that embeds it breaks. Turn them on under Security.
  • A network you created yourself does not come across. Apps in the same Environment share one network, so put stacks that talk to each other in the same Environment.
  • A service name already used by another stack is renamed. The second db in one Environment arrives as <app>-db, and its depends_on, variables and domain follow.
  • A bind mount comes across with its contents, single files included. A bind that names a file copies that file alone, not the directory around it.
  • A ${{project.KEY}} reference becomes a real link. A value that is exactly one reference to a project or environment variable of the same name arrives linked to that shared variable. When the names differ, the resolved value arrives instead and the report says so.
  • Every variable arrives plain. Dokploy has no secret variables, and Deplo never guesses from the name, because a secret is write-only and cannot be read back. Mark what you want Secret under Variables afterwards.
  • Imported basic-auth credentials are flagged. They never went through Deplo's password policy or the breach check.
  • Anything that needs a permission you do not hold goes in the report, with who can turn it on. For security reasons host bind mounts, privileged, published ports and foreign networks or volumes each need their own permission.

What is left behind

  • LibSQL. There is no engine for it here.
  • Deploy keys and connected-source credentials. Attach a git connection for a private repository.
  • Private registry passwords. Dokploy never exposes them. Add the registry under Registries before you deploy.
  • A compose file kept in a git repository. Dokploy does not return it over the API. The app is created and the report tells you to paste the file in.
  • A Traefik middleware written into an app's own file. The report names it with its kind. Define it in the proxy's configuration here, then add it to the domain.
  • The machine's own files. /etc/localtime, /etc/hosts, /etc/resolv.conf and similar belong to the host. The destination already has its own.

Backing out

  • While the run is going, in any step. Stop and undo removes everything the run created here with its data, starts again what it stopped on Dokploy, and removes the agent from the source. Dokploy keeps all of its data.
  • A run that fails on its own during the data step. Nothing is rolled back. A service whose data did not arrive refuses to deploy. The agents stay, so the copy can run again.
  • A takeover, before the ports move. Cancel and remove Deplo starts every service the migration stopped, starts Dokploy's own containers again, removes everything Deplo created here, and uninstalls Deplo. It asks for the API key again.
  • A takeover, after the ports move. The snapshot is the only way back. If the port move itself fails, Deplo puts the ports back, starts Dokploy again and offers Try again with the reason.

Running the migration again is safe. What is already here is kept, and its data is copied again when you tick it.

Troubleshooting

SymptomWhat to check
The scan finds nothingWrong panel address, or the key has no access. Dokploy keys are per organization.
Dokploy stopped accepting the key part-wayThe key hit its rate limit. Raise or disable it under Settings, Profile, API/CLI, then run the import again. Everything already here is skipped.
The panel's certificate is not trustedDeplo cannot accept an untrusted certificate. Use Dokploy's plain http address.
A 502, or a Cloudflare 521It comes from the proxy or CDN in front of the panel. Start it, or point Deplo at the panel's own address.
Stuck on Waiting for the agentThe install command has not run on that machine, or the machine cannot reach this one.
The server agent did not install during a takeoverRe-run /opt/deplo/install.sh on the machine, or use the command under Settings -> Servers.
One source machine does not answerIts services are named in the report and blocked from deploying. The other machines are still copied. Check inbound 9443 with nc -vz <source-ip> 9443.
A volume arrives emptyThe app refuses to deploy until you decide. One volume has six hours to copy, so a very big volume over a slow link is better copied by hand.
A single-file bind is refused by nameThe destination server's agent is too old. Update that agent and copy the data again.
The data step fails half wayNothing is rolled back. Only Stop and undo does that. A second run skips what is already here and copies the data again, or use Copy the data again on the app.
Two apps mount the same absolute pathThe copy empties its target before writing, so Deplo refuses and names the other app. Give one of them its own directory.
The port move failedDeplo put the ports back and started Dokploy again. The step names what is holding the port, next to Try again.
Stuck on Moving the portsThe host part never ran. On the machine, systemctl status deplo-takeover and /var/log/deplo-takeover.log say why. Run curl -fsSL https://deplo.build/install.sh | bash again and the takeover continues where it was. Until the ports move, stay on the http address: the https one still belongs to the old panel and answers 404.

More in Servers and agents.

Next steps

Did this page help you?

On this page