Move from Coolify

Beta

Read a Coolify 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 Coolify installation over its API and recreates it here: projects, applications, one-click services, databases, domains, variables, volumes and backup destinations, with the data copied across. The configuration comes from the API. The data is read by a Deplo agent installed on each Coolify server.

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

Before you start

Turn the API on and create a token

If Coolify's API is off, the scan says API is disabled. Turn it on under Coolify's Settings. If the API is limited to a list of addresses, add the machine Deplo runs on, or the scan says You are not allowed to access the API.

Then go to Keys & Tokens, API tokens. Tick root and create the token from an account that is an admin or owner of the team. Root covers both things a migration needs: reading your values and stopping a service before its data is copied.

If you do not want to grant root, tick deploy first, then read and read:sensitive, in that order (Coolify clears the list when deploy is ticked). Without read:sensitive every variable, database password and one-click compose file would arrive empty. Deplo checks this at Connect and refuses to import blanks.

One run per source team

A Coolify token only sees the team it was created in. For each extra team, switch team in Coolify, create a token, paste it here and press Add. It joins the Teams to bring over list with the Deplo team it lands in. Two Coolify teams may land in the same Deplo team, or each in its own.

Each team 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

A Coolify instance often has more than one server. The Install step lists every one.

  • 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 Coolify 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 Coolify. 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 Coolify 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=coolify.

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 Coolify 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 Coolify and everything it runs, and goes straight to Take over.

Connect, Install, Review. The panel is already filled in. Paste a token per Coolify team, 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 team 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 coolify to confirm.

Deplo then stops Coolify and its apps, copies its certificates, moves Traefik onto ports 80 and 443, removes Coolify's containers, networks, images and directory, and restarts Docker. Volumes and Coolify'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 CoolifyHere
Application, nixpacks / static / dockerfileApp built from its git repository
Application, dockerimageApp running that image
Application, dockercomposeCompose stack
Service (one-click)Compose stack, from the compose its author wrote
PostgreSQL, MySQL, MariaDB, MongoDB, Redis, ClickHouseThe same database engine
KeyDB, DragonflyNothing. Named in the report
Persistent storageVolume, with its data
File storageConfig file under Storage
Environment variablesThe app's variables, magic SERVICE_* values already resolved
Preview-only variablesThe app's preview variables
Shared variables (team, project, environment, server)Shared variables at the same level, 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
Scheduled tasksCron jobs
S3 storagesBackup destinations, tested on arrival
Scheduled database backups to an S3 storageBackup schedules, on the destination that came with them

What changes on the way

  • Temporary hostnames get a new address. A name on sslip.io, traefik.me, 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 volume keeps the name you gave it. Coolify stores it as <resource id>-<name>. It arrives as plain <name>.
  • A volume pinned by name in the compose file is not the one that was running. Coolify renames every volume to <resource id>_<key> and ignores external: true and name:. Deplo copies what was actually running. The report names the pinned volume so you can decide what to do with it.
  • The compose is the one its author wrote, not the copy Coolify renders with its own labels and networks. Deplo adds those itself.
  • 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 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 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 config file Coolify keeps at a real path on the host lands in Deplo's own files directory. A bind that names a file copies that file alone.
  • A {{team.KEY}} reference becomes a real link. A value that is exactly one reference to a shared variable of the same name arrives linked to it. When the names differ, the resolved value arrives instead and the report says so.
  • A server-level shared variable is offered to the project. Deplo has no server scope.
  • A variable is a secret here only if Coolify marked it one. Deplo never guesses from the name, because a secret is write-only and cannot be read back. Variables Coolify marks shown once arrive plain and empty, because its API returns no value for them. The report names the keys. Fill them in under Variables before you deploy.
  • An address stored without a scheme arrives on plain http. The report names it. Add a certificate under Domains when you want https.
  • A template address recorded without a port still routes. Deplo reads the port from the service, and the report says which one it took.
  • A $ Coolify would have expanded is named. The value arrives as it was written.
  • 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.

What is left behind

  • KeyDB and Dragonfly. There is no engine for either here. Both are named in the report.
  • Coolify's own COOLIFY_* variables. They name the panel you are leaving.
  • Deploy keys and connected-source credentials. Attach a git connection for a private repository. This also turns on auto-deploy.
  • Private registry passwords. Coolify never exposes them. Add the registry under Registries before you deploy.
  • A volume's own backup to an S3 storage. Coolify's API never lists those schedules. Set it again under Backups: one app backup here covers every volume of the app.
  • A database backup saved only to the local disk. There is no destination for it here. The report names it.
  • The machine's own files. /etc/localtime, /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 Coolify, and removes the agent from the source. Coolify 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 Coolify's own containers again, removes everything Deplo created here, and uninstalls Deplo. It asks for the token 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 Coolify 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
API is disabledTurn the API on in Coolify's settings.
You are not allowed to access the APICoolify's IP allowlist does not include this machine.
This token cannot read values, or cannot read compose filesThe token is not root and has no read:sensitive, or its account is not an admin or owner of the team.
This token cannot stop a serviceThe token is not root and has no deploy. Create a new one with root ticked.
Coolify refused the tokenThe token expired or was revoked.
Rate limitedCoolify allows 200 requests a minute. Wait and try again.
The panel's certificate is not trustedDeplo cannot accept an untrusted certificate. Use Coolify'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 shared-variable level is missing from the reportAn older panel has no endpoint for it. Copy those in 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 Coolify again. The step names what is holding the port, next to Try again.

More in Servers and agents.

Next steps

Did this page help you?

On this page