Migration
Several ways in, one plan. Every migration is analysed and turned into a plan you can read before a single file is written, and the result is previewed and verified on the new server before DNS moves. Read what to expect first, then the guide for your source.
One guide per source
Every source ends in the same place (a plan you read, a site you look at before DNS moves, a verification you can paste into a ticket) and each one gets there differently. Start with the guide for the machine you are leaving.
- DirectAdmin
- The live server read over SSH with one command, planned per domain, and moved with a pre-copy and a final delta; or a DirectAdmin user backup archive. Migrating from DirectAdmin.
- cPanel/WHM
- Packaged on the source by
pkgacctas root, or by cPanel's own API as the account itself, or an archive you already have. A nestedhomedir.taris handled. Migrating from cPanel and WHM. - A Linux server over SSH
- No panel at all: a document root and its databases, pre-copied while the site stays live.
wp-config.phpand.envare read for credentials so you do not have to type them. Migrating a Linux server over SSH. - Another KLYRN server
- The Move: the source mints a read-only grant for one account, the destination pulls over the pinned panel port, and the configuration travels instead of being guessed at. Moving between two KLYRN servers.
An archive is analysed by inspecting, extracting and parsing it, and applied in one pass. A site reached over SSH is measured in place and copied straight into the site it will live in, in two passes. The plan you review looks the same either way; what differs is where the downtime is, and each guide says so.
From an archive
klyrn import cpanel /root/backup-acme.tar.gz
klyrn import directadmin /root/user.acme.tar.gz
klyrn import archive /root/backup.tar.gz # detect the kind
klyrn import list
klyrn import show 1 # what was found and what will be created
klyrn import apply 1
klyrn import delete 1
Analysis is separate from application on purpose. show tells you the domains,
the databases, the cron entries, the PHP version the source used and anything KLYRN cannot
carry across. Nothing exists on the server until apply.
klyrn import apply 1 --account acme
klyrn import apply 1 --domains example.com,shop.example.com
klyrn import apply 1 --databases acme_wp
klyrn import apply 1 --no-cron --no-ssl
In the panel the archive is uploaded with a progress bar, the plan is reviewed on screen, and the results end with the DNS cut-over list.
Over SSH from a live server
# A live cPanel server, with root on the source
klyrn import ssh --host old.example.com --user root --account acmeuser
# A cPanel account, without root on the source
klyrn import ssh --host old.example.com --user acmeuser --password '…'
# Any server at all: a document root and its databases
klyrn import ssh --host old.example.com --user deploy --key ~/.ssh/id_ed25519 \
--mode files --domain example.com --path public_html \
--db acme_wp:acme_wp:secret
Authentication is a password or a private key file; encrypted private keys are not supported yet.
--fingerprint SHA256:… pins the source's host key: the key is compared during the handshake
and a mismatch is refused before the password is offered, naming both fingerprints.
What each refusal means.
On 0.3.5‑beta.1 that pin is the only one there is: pass --fingerprint yourself
for a source you will connect to more than once. Recording the key automatically on the first connection,
approving it, and managing the record in the panel are built and not yet released.
--db is repeatable and takes
name:user:password[@host[:port]]. In files mode KLYRN also reads
wp-config.php and .env under the document root, so a WordPress
site usually needs no --db at all.
.htaccess and what does not come across
nginx does not read .htaccess. KLYRN reads it for you, translates the rules
it understands into the site's nginx configuration, and shows you the translation before
applying it. Rules it cannot translate are listed rather than dropped.
Said plainly, because a migration that surprises you is worse than one that refuses:
- Mail is not migrated. KLYRN hosts no mail. Mailboxes, forwarders, autoresponders and filters stay with your mail provider, and the MX records never change.
- DNS zones are not imported. KLYRN is not a nameserver. The cut-over list at the end says exactly which records to change.
- Anything the source refuses to give up. A missing document root, or one that is the home directory itself, is reported rather than guessed at.
- Apache-specific behaviour beyond the rules KLYRN can translate. It is listed, so you can decide.
Previewing before DNS moves
The imported site is live on the new server the moment apply finishes, and nothing points at
it yet. The preview asks the new server's own nginx for the site by name (the primary,
www if the site serves it, every alias and redirect) exactly as a visitor will once DNS
points here. Redirects are not followed, deliberately: where a name sends people is part of the answer.
The report also hands you the lines to do the same from your own machine, with your names and address filled in:
curl -sS -I --resolve example.com:443:203.0.113.10 https://example.com/
The preview is a request to the new server. It does not fetch the old one and cannot tell you the two pages look the same. Comparing them is your job, and it is the step worth doing: a blank page returns HTTP 200.
Verifying and cutting over
After an import, and before any DNS changes, KLYRN produces a verification report on the new
server: eleven checks, each passed, warning or action required, each carrying its evidence.
It also hands you the exact curl --resolve and hosts-file lines to look at the
imported site yourself while the old server is still serving the public.
The report checks the new server, not the old one. It does not connect to the source and cannot tell you the two pages render the same. Comparing them is the step that matters, and it is yours. What each check proves, and what “verified” does not mean.
- Import and applyThe sites, databases and cron entries exist on the new server, but nothing points at it yet.
- VerifyCompare against the source. Fix what differs.
- Lower the TTL at your DNS providerHours before the cut-over, not at it.
- Change the recordsThe cut-over list names them. If Cloudflare holds the zone,
klyrn dns pointwrites them. - Issue certificates
klyrn site ssl <domain>, or wait: the scheduler retries every ten minutes. - Keep the old server for a weekLong enough for every cached record to expire and for anything you missed to surface.
Full walk-through with screenshots: Migrating to KLYRN.