DEV Community

Cover image for Switch from Coolify, Dokploy or CapRover Without Touching the Old Server
GDS K S
GDS K S

Posted on Edited on

Switch from Coolify, Dokploy or CapRover Without Touching the Old Server

Updated 2026-10-19 against the Levelrail 0.6.0 docs. Since the first version of this post, Levelrail started shipping stable releases.

Switch from Coolify, Dokploy or CapRover Without Touching the Old Server

Migrations go wrong when the tool changes the thing you are leaving. The importer in Levelrail follows the opposite rule: it only reads from your old platform. The source keeps running the whole time, so a bad import costs you nothing but a cleanup.

This guide walks the whole path, including the parts that do not migrate. The list is long, and learning that in week two costs more than learning it now.

TL;DR

Step What happens Touches the old server?
1 Make a read token on the old platform Read only
2 Run a dry run Read only
3 Apply the import Read only
4 Move data by hand Reads dumps
5 Switch DNS when the new app is healthy No

How the importer behaves

It reads a live Coolify, Dokploy or CapRover instance through that platform's own HTTP API. It never stops, edits or deletes anything there. A test asserts it sends nothing but GET requests, apart from CapRover's single login POST.

You can run it from the dashboard under Settings, Import from another platform, from the CLI, or over the API. All three use the same two routes.

Step 1: get a token

Platform Credential Notes
Coolify API token Use read:sensitive to get real env values
Dokploy API key Sent as an x-api-key header
CapRover Login password Exchanged for a session token

The token travels to the Levelrail control plane in the request body. The control plane holds it in memory only. It never stores it, logs it or writes it to the audit log, and it scrubs the token from error text. Put it in an environment variable instead of the command line so it stays out of your shell history:

export APP_IMPORT_SOURCE_TOKEN=your-token
Enter fullscreen mode Exit fullscreen mode

Step 2: always dry run first

levelrail-cli import platform coolify --url YOUR_COOLIFY_URL --dry-run
Enter fullscreen mode Exit fullscreen mode

Swap coolify for dokploy or caprover as needed. The dry run reads the source and prints one row per item with a status. It creates nothing.

Status What it means
Ready Maps cleanly, nothing for you to do
Needs attention Gets created, with a caveat and a suggested manual step
Not supported Cannot import, with the reason and what to do instead

Read every Needs attention and Not supported row. That list is your real migration plan.

My source is on a private network

The control plane refuses private addresses by default, because an import URL is an outbound request an operator controls. Allowing it takes two opt-ins together. The operator sets APP_IMPORT_ALLOW_PRIVATE_NETWORKS=true on the control plane, and the request adds --allow-private. Either one alone gets a 400.

Cloud metadata and link-local addresses stay blocked even with both opt-ins. No legitimate use points an importer at an instance metadata service.

Step 3: apply it

Import everything, or a subset:

levelrail-cli import platform coolify --url YOUR_COOLIFY_URL --only web,api
Enter fullscreen mode Exit fullscreen mode

Apply is safe to repeat. Every imported app carries a label with its source id, and a re-run skips apps it already made. If it fails halfway, run the same command again and it retries only the unfinished items. The command exits non-zero when anything failed, so a script can retry.

If a name is already taken, the default adds a numeric suffix. Pass --collision skip to leave it alone instead.

What moves and what does not

This table is the honest core of the post.

Moves Arrives as
Apps An app with image or git source, port, build method
Env vars Plain env, or encrypted secrets when the name looks sensitive
Domains Declared on the app
Volumes Created empty
Databases Created empty (Postgres, MySQL, MariaDB, MongoDB, Redis from Coolify and Dokploy)
Does not move What to do
Database contents Dump the source, restore with the backup tools
Volume contents Copy the data across before starting the app
Git-built apps Arrive with a pending image, so you connect the repo and run a build
CapRover images CapRover builds locally, so push to a registry or connect a repo
Compose stacks and one-click services Reported unsupported, deploy the compose file separately
Certificates, DNS, history, logs, metrics Re-point DNS only after the new app is healthy
Cron jobs The report lists schedule and command so you can recreate them

Secret-looking names (password, token, key, credential, DSN and similar) go through the secrets manager. Coolify redacts values unless the token has read:sensitive, and a secret that comes back empty is skipped and flagged.

Step 4: finish by hand

The importer lists what remains. A checklist beats memory:

  • [ ] Read every Needs attention and Not supported row
  • [ ] Restore database dumps and copy volume data
  • [ ] Connect repositories and trigger builds
  • [ ] Confirm secrets landed on each app
  • [ ] Check domains
  • [ ] Re-add health checks and cron jobs
  • [ ] Switch DNS last

Keep DNS pointing at the old server until the imported app is healthy.

Undoing an import

Nothing on the source changed, so nothing needs undoing there. To remove what the import created, list the apps and databases from the apply report, then delete them:

levelrail-cli apps delete your-app
Enter fullscreen mode Exit fullscreen mode

Delete the databases the report listed and any now-empty projects.

What to check before trusting it

Levelrail is young. Single-server deployments are labeled production ready, while multi-node and a handful of newer features are still beta. Each label links to its evidence on the feature status page. The importer covers apps, databases, env vars, domains and volumes, but it cannot read inside your data. Treat the dry run as a plan, rehearse a database restore, and keep the old platform alive through a full business cycle.

Live Dokku import over SSH does not exist. Code can map a Compose file and a Dokku environment dump, but the API, CLI and dashboard do not expose those two yet.

What would stop you from migrating today: the empty database step, the stack of manual items, or the maturity of the project?

Frequently asked questions

How do I migrate from Coolify to Levelrail?

Install Levelrail, create a read-only API token in Coolify, then run levelrail-cli import platform coolify --url YOUR_COOLIFY_URL --dry-run. Review the plan, then run it again without --dry-run. The old server is never stopped or edited.

Can I migrate from Dokploy or CapRover too?

Yes. Swap coolify for dokploy or caprover in the same command. The importer covers apps, databases, env vars, domains and volumes, but it cannot read inside your data.

Will my databases come over with their data?

No. Databases are created empty, so you restore the data yourself and rehearse that restore before cutting over.

Is Levelrail a Coolify alternative worth migrating to?

It depends on what you need. See the full comparison and the Coolify alternative page. Single-server deployments are labeled production ready, and multi-node plus a handful of newer features are still beta. The latest release is v0.6.0 (2026-10-17), and the feature status page links the evidence behind each label.

Go deeper

Try it, and tell me what breaks

Levelrail is open source under Apache 2.0. It is young, so every bug report changes what gets built next.

GitHub logo glincker / levelrail

Free, self-hosted alternative to Vercel, Heroku, Railway, Coolify and Dokku. Push to git, get HTTPS, logs, metrics and one-click rollback on your own servers. One Go binary, no Kubernetes.

Levelrail logo

Levelrail

The lightweight, self-hosted alternative to Vercel, Heroku, Railway, Coolify and Dokku.
Push to git. Get HTTPS, logs, metrics and one-click rollback on your own servers.
One Go binary · Docker runtime · agents instead of SSH · observability built in · no Kubernetes

Latest release License: Apache 2.0 GitHub stars CI Discord
Single server: production ready Multi-arch container image on GHCR Go version MCP server Documentation Last commit PRs welcome

Website · Docs · Install · Production ready · Compare · Guides · Roadmap · Changelog · Discussions · Discord

Levelrail: your own Vercel, on your server. The lightweight, self-hosted alternative to Vercel, Heroku and Coolify.

Levelrail is an open source (Apache 2.0) self-hosted PaaS: a Vercel and Heroku alternative that runs on any Linux server you own, from a $5 VPS to a rack. It turns plain servers into a private cloud with Git deploys, automatic HTTPS, databases with verified backups, metrics, logs and alerts, without Kubernetes and without the monitoring stack you would otherwise bolt on.

Install in one command

Needs a Linux server (amd64 or arm64) with systemd and root. Docker is installed for you if…




If this post saved you time, a star on the repo helps other self-hosters find it. Bugs and feature requests go in the issue tracker.


GDS K S · thegdsks.com · building Glincker · follow on X @thegdsks

The safest migration is one where the old server never knows it happened.

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.