BAUER GROUP - Coolify Migration Toolkit
Today, Tomorrow, Together | Building Better Software Together
Moves a Coolify project — with its data — between servers, and relocates a whole Coolify instance to a new host. Failsafe, resumable, and rollback-capable.
Coolify can clone a resource to another server but deliberately will not move the
data. VolumeCloneJob and CloneMe's cloneVolumeData flag exist upstream, but
PR #4777 shipped them disabled. The maintainer's stated blockers — permission
damage, job-queue spam at 50+ resources, no progress tracking, large-volume
failures — are all consequences of running inside Coolify's Laravel queue. An
external orchestrator has none of those constraints. That is what this is.
Repository Information
- Version: v2.8.2
- Repository: bauer-group/IP-CoolifyMigration
- Branch: main
- Architecture: Pure-logic cores with thin IO shells; saga engine with a crash-safe journal
Features
- Application-unaware mirroring — a cleanly stopped stack makes a volume just bytes. No per-engine logic, no supported-database allowlist. Postgres, MySQL, MariaDB, MongoDB, Redis, KeyDB, Dragonfly, ClickHouse and anything else you run are all handled the same way, because none of them are special once stopped.
- Byte-exact —
rsync -aHAXS --numeric-ids, parallelised, with SHA-256 and metadata verification on both sides. Neverchown. - Failsafe — every step has a compensating action, journalled to disk. The
source is never destroyed until you explicitly say so, so rollback is always
available.
resumereconciles against reality, not against the journal. - DNS gate — extracts every Traefik/Caddy hostname and refuses to start the target while DNS still resolves to the old server, with an actionable cutover checklist.
- Honest about drift — the target is built exactly as the source is
configured, but a tag is a pointer and a branch moves. We detect a floating
latestthat could cross a database major, or a HEAD that has moved, and put the concrete question to you rather than deciding for you. - Server migration — relocate the whole Coolify instance, with the
APP_KEYtreated as a first-class, asserted artifact rather than a lucky side effect. - Proven, not assumed — an integration rig of two real sshd containers
asserts that uid 999, hardlinks, xattrs, sparse files and symlinks survive an
actual rsync, and that a wrong
chownis caught by verification.
Architecture
| Layer | Role |
|---|---|
domain/ |
Pure logic: classification, compose analysis, volume pairing, drift, state machine |
api/ |
Coolify REST client with per-endpoint request whitelists |
discovery/ |
Docker + API reconciliation; the label-based quiesce gate |
transfer/ |
asyncssh, rsync planning, checksum verification |
journal/ |
Append-only crash-safe state |
dns/ |
FQDN extraction, authoritative resolution, cutover gate |
ui/ |
Rich dashboard, wizard, and a plain non-TTY fallback |
Requires the instance API switched on (Settings > API — off by default) and a token with
rootorread:sensitive. Without the switch every call is403 "API is disabled.", which looks like a token problem but is not. Without the scope, Coolify'sApiSensitiveDatamiddleware silently omitsvalue,real_valueanddocker_compose_rawfrom responses — no error, no redaction marker. The tool checks both at startup and fails closed.
Quick start
pip install bg-coolify-migrate
export COOLIFY_URL="https://coolify.example.com"
export COOLIFY_TOKEN="..." # root or read:sensitive
coolify-migrate doctor # verify token scope + server reachability
coolify-migrate list # everything: server -> project -> env -> resource
coolify-migrate list my-project # limited to one project
# Scope with a selector: project / project/environment / project/environment/resource
coolify-migrate plan my-project --to target-server # whole project (dry run)
coolify-migrate run my-project/production --to target-server # one environment
coolify-migrate run my-project/production/api --to target-server # one resource
Omit the selector in a terminal and plan/run open an interactive picker.
Interrupted? coolify-migrate resume <id>. Regret it? coolify-migrate rollback <id>.
Server migration
coolify-migrate server plan --to new-host.example.com
coolify-migrate server run --to new-host.example.com
Documentation
See docs/: installation, configuration, cli, architecture, safety,
server-migration, troubleshooting.
License
MIT © BAUER GROUP
Release files for bg-coolify-migrate 2.8.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bg_coolify_migrate-2.8.3.tar.gz | 376.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bg_coolify_migrate-2.8.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 603.6 kB
Release files / bg_coolify_migrate-2.8.3.tar.gz
| Download URL | bg_coolify_migrate-2.8.3.tar.gz |
|---|---|
| Size | 376.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b3f49701622e9f73493808634e331025b09199e4f694c2b4d8cd9d29b28368cf
|
|
BLAKE2b-256 checksum How to use checksums |
45f510d16723e760785bf510c6fddd90d495e3e630991150f1e04d901a187920
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / bg_coolify_migrate-2.8.3-py3-none-any.whl
| Download URL | bg_coolify_migrate-2.8.3-py3-none-any.whl |
|---|---|
| Size | 227.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aab73c0e6c848adc6cdcdedcf453c6c69f2fb54d8889023f7234180c887765e2
|
|
BLAKE2b-256 checksum How to use checksums |
2150ab783ecf0f49edcbee76388c33909742a93f56d975b8637e152456113c26
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|