Prerequisites
- Levelrail installed on the new server, signed in with the CLI (
levelrail-cli auth login). - A Coolify API token. Use the
read:sensitiveability, or secret values come back empty. - The Coolify URL reachable from the Levelrail control plane. For a private address, set
APP_IMPORT_ALLOW_PRIVATE_NETWORKS=trueon the control plane and pass--allow-private. - For apps built on the Coolify host: SSH access to it with a login that can run
docker(root or thedockergroup). - For databases: a database user on each Coolify database, and a route from the Levelrail node to its port.
What imports automatically
What needs a manual step
- Database contents are copied by a separate step (below).
- Volume contents are copied by
rsynccommands you run. - Images built on the Coolify host exist nowhere else. Use the Move images step.
- Git-built apps do not build by themselves. Connect the repository (with credentials for a private one) and run a build, or let verify do it.
- Old database hostnames in env vars are only rewritten through a mapping you confirm.
- Secrets the token could not read are skipped and flagged.
- Cron jobs, extra ports, raw host port mappings, command-style health checks are called out as needs attention.
What cannot be migrated
- Coolify one-click services and Docker Compose apps (multi-service). They are listed as unsupported. Deploy their compose file with compose apps.
- TLS certificates, DNS records, deploy history, logs and metrics. Certificates are issued here on first use.
- ClickHouse, KeyDB and Dragonfly databases through the copy step. Use their own dump tools and the restore tools.
Steps
1
Plan
Dashboard: Settings, Import from another platform, “Move apps from Coolify”. CLI:Every app and database gets a verdict (ready, ready with notes, needs attention, unsupported) with the reason. Nothing is created.
2
Stage
appimp-123. Re-running skips what exists. Use --map OLD_DB_HOST=NEW_DB_HOST for hostnames you want rewritten, shown with a masked before and after.3
Move images built on the Coolify host
docker save over SSH and checks the loaded image by content. The target must be the control plane node for now.4
Copy databases
levelrail-cli migrate server --engine postgres --host db.old.example.com --user admin --password-stdin --plan, then --apply.5
Copy volumes
import platform, enter the file and byte counts from both hosts on the checklist instead (levelrail-cli migrate step APP data_verified --volume NAME=SRC_FILES:SRC_BYTES:DST_FILES:DST_BYTES).6
Verify
curl --resolve app.example.com:443:NEW_IP https://app.example.com/healthz.7
Cut over
levelrail-cli import cutover rollback --session appimp-123 --app web.8
Retire Coolify
Stop Coolify only after a full traffic cycle and a checked backup. Download the receipt first:
levelrail-cli import apps --session appimp-123 --receipt.Databases
The copy streamspg_dump, mysqldump or mariadb-dump, mongodump or a Redis RDB snapshot from the source into the managed database, then compares row counts per table. It is safe to repeat: the restore replaces the target in one transaction. The source is only read.
Coolify databases often have no published port. The Levelrail node must reach the database host and port. Publish the port in Coolify temporarily (restricted by firewall to the new server) or use the migrate server --container path when the database container runs on the same node.
Downtime window
Pause or put the old Coolify app into maintenance mode before the final database copy, so no write lands after it.
Domains and TLS
- Lower the TTL a day ahead.
levelrail-cli migrate cutoverreturnsgo,wait(TTL too high),no-go(not healthy here) orswitchedper domain. - The guided cutover switches a domain by the first method that applies: a connected Cloudflare or Route 53 record (previous value stored for rollback), the managed proxy route, or a record you set by hand followed by
import cutover confirm-dns. - It then checks the public name and rolls back on its own if that fails within
APP_CUTOVER_VERIFY_TIMEOUT(5 minutes). - Coolify’s Traefik may own ports 80 and 443. Install Levelrail in coexist mode first, or switch DNS to a new server.