All documentation
  1. Home
  2. Docs
  3. What to expect

What to expect from a migration

Read this before you move anything. It says what KLYRN carries across, what it only reports, what “verified” means precisely, and the one thing that has never been tested.

The thing to know first

No archive produced by a real cPanel or DirectAdmin server has ever been fed to KLYRN's parsers. Every fixture in the test suite was written from those vendors' published documentation, by the same people who wrote the parsers. A fixture written by the author of a parser tests it against their belief about the format, not against the format.

What has been done: the parsers, the .htaccess translation and the pre-cutover report all have tests and the tests pass, and every route has been run end to end on a test server against a stand-in source that produces a genuine archive layout and answers the same commands. That exercises SSH, the root check, detection, invocation, streaming, cleanup and the whole pipeline. It does not exercise cPanel.

The gaps a hand-written fixture cannot cover, and which a real archive would:

  • Encoding and line endings. A decade-old server carries files touched by a decade of tools: byte-order marks, CRLF, a Latin-1 comment in a config file.
  • Scale. Hundreds of addon domains, thousands of files, a multi-gigabyte dump, hundreds of grant lines.
  • Version drift. Both vendors change these formats between major versions.
  • Damaged archives. A backup interrupted halfway, or metadata naming a domain with no matching file. The parsers are written to degrade rather than guess; that claim is untested against real damage.
  • Character set and collation in database dumps, which is where a migration corrupts text silently rather than failing.

This is why the parsers report rather than guess: anything not understood becomes a warning on the plan, never a silent omission. That makes the gap survivable. It is not a reason to pretend it is not there.

So: keep the old server running. Check the imported copy on the new server before you touch DNS, and leave the source alive for a week afterwards. Every part of KLYRN's migration is built for that order.

What is carried across

Files
The document root and everything under it, handed to the destination account: owner set, setuid and setgid bits stripped, symlinks copied as links and never followed. An archive is read as real tar headers before anything running as root is pointed at it: a name that escapes the directory, a symlink or hard link whose target leaves it, a device node, a named pipe or a member type KLYRN will not extract are each refused by name.
Domains
The primary domain, and the addon, parked and subdomain entries the source records, each with its own document root and PHP version.
PHP version
Mapped from the source's own notation to a version KLYRN has. A domain set to inherit resolves from its parent.
Databases and their users
The dumps are restored and the users recreated with their original password hashes, so the credentials already in your application's configuration file keep working unchanged. Grants are parsed, including quoted and backtick-escaped database names.
Scheduled tasks
The crontab, rewritten to run as the new account's user.
The application's shape
Each document root is identified as WordPress, Laravel, plain PHP or static, so the site is created as the right type rather than as a guess.

Nothing is written until you have read the plan. Analysis and application are separate commands on purpose. klyrn import show <id> lists every domain, database, database user and cron entry with its conflicts and warnings; klyrn import apply <id> is the first thing that creates anything, and it takes --domains, --databases, --no-cron and --no-ssl if you want less than all of it.

What is only reported, never moved

Said plainly, because a migration that surprises you is worse than one that refuses.

Mail
KLYRN hosts no mail and never will in V1. Mailboxes, forwarders, autoresponders and filters stay with your mail provider. The analysis counts the mail domains and mailboxes it finds and records them explicitly, so the number is in front of you before you move rather than after. Your MX records are not touched.
DNS zones
KLYRN is not a nameserver, so there is no zone to import. What you get instead is a cut-over list at the end of the import: exactly which records to change, and where.
Anything the source will not give up
A missing document root, or one that is the home directory itself, is reported rather than guessed at. Anything the parser does not understand becomes a warning on the plan.
Apache behaviour nginx does not have
Listed, per directive, so you can decide. See below.

The mail trap after a cut-over is an MX record pointing at the new server. KLYRN runs no mail server, so it would refuse every message. The verification report checks for exactly this and marks it as action required, naming the record.

What happens to .htaccess

nginx does not read .htaccess, and it does not read it after a migration either. KLYRN reads it for you instead, and the invariant is that every directive line is classified exactly once, so nothing is silently dropped. Three outcomes:

How each directive is classified
ClassificationWhat happens
ConvertedTurned into nginx that KLYRN generates, tested with nginx -t before it is ever loaded, and shown to you before it is applied. It is applied only when you say so.
Needs reviewUnderstood, but not something to translate without a person reading it. Listed with the file and line it came from.
Not possiblenginx has no equivalent. Listed, so you know what stops working before you cut DNS rather than after.

Three shapes are handled specially, because getting them wrong is how a converted site breaks quietly:

  • A WordPress front-controller block needs no nginx equivalent at all (KLYRN's own vhost already does it), so it is not converted into something redundant.
  • Forced HTTPS is recognised as already done, rather than converted into a second redirect on top of the one KLYRN issues.
  • www and bare-name redirects are converted only when this server actually answers for the target. A redirect to a name this machine does not serve is a loop waiting for the cut-over.

The scan is bounded so it cannot depend on how patient the panel is: up to 40 .htaccess files, six directories deep, 256 KB each. A site with more than that gets the first 40, and the report says so.

The report also catches the two ways a conversion goes stale: nginx still serving rules from an .htaccess that has since been deleted, and an .htaccess that was edited after it was converted. Both are reported as action required rather than left to diverge.

The preview: seeing it before DNS moves

The imported site is live on the new server the moment apply finishes, and nothing points at it yet. The preview is how you look at it anyway. It asks the new server's own nginx for the site, with the site's Host header (which is exactly what a visitor gets once DNS points here), and it does that for every name the site claims: the primary, www if the site serves it, and each alias and redirect.

Redirects are not followed, deliberately: where a name sends people is part of the answer, not something to resolve away.

You are then handed the exact lines to do the same thing from your own machine, so you are not taking the server's word for it:

curl -sS -I --resolve example.com:443:203.0.113.10 https://example.com/

… and a hosts-file line for the same names, so you can browse the migrated site in a real browser while the old one is still serving the public.

What the preview is not. It is a request to the new server. It does not fetch the old one, and it 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. KLYRN once shipped a beta where every WordPress site rendered nothing and answered 200 while doing it.

What &ldquo;verified&rdquo; actually means

The verification report is eleven checks, each returning passed, warning or action required, each carrying the evidence that produced it, and the whole thing copyable as text for a support ticket. The overall result is the worst row: one action required and the report says action required.

The eleven checks, and what each one proves
CheckWhat it establishes
FilesThe document root exists, has files in it, and they belong to the account. Files still owned by root are the classic leftover of an archive unpacked in the wrong place, and the site half works.
DatabasesThe databases are here, with their table counts, and (the part that matters) the application's own credentials still open one. It reads wp-config.php and connects with what it finds. A site whose files arrived and whose config still points at the old server looks fine until the first page load.
DomainsEvery name the site claims is in this site's own vhost, rather than falling through to the server that answers for anything unclaimed.
RuntimeThe thing that runs the site is running, and actually ran: a PHP site serving its own source as text is the failure this catches.
HTTPWhat the primary name returns from this server, with the timing.
SSLWhether there is a certificate and which names are on it. No certificate before the cut-over is normal, not broken, and the row says which of the two it is.
RedirectsEach redirect proved by asking for it, rather than by reading the configuration that was supposed to create it.
CronThe scheduled tasks that came across, and the ones attached to the account rather than to a site.
.htaccessEvery directive accounted for, and whether the conversion has gone stale.
DNSOnly when you ask for it: where each name resolves today, against this server's address. Without asking, the row says “not checked” rather than implying it passed.
MailWhere the MX records point, and an action if one of them points here.

Read this part carefully. Every one of those checks runs against the new server. The verification does not connect to the source, does not diff the two sites, and cannot tell you a page renders the same as it used to. It proves the new server is internally consistent and answering. Comparing the two with your own eyes, while the old one is still up, is the step nothing here replaces.

The cut-over, in the order that works

  1. Import and applyThe sites, databases and cron entries exist on the new server. Nothing points at it.
  2. Preview and verifyLook at the imported site with the curl and hosts lines. Read the report. Fix what it names.
  3. Lower the TTL at your DNS providerHours before the cut-over, not at it. This is the one step people skip and then wait a day for.
  4. Change the recordsThe cut-over list names them. If a connected provider holds the zone, klyrn dns point writes them.
  5. Let the certificate arriveklyrn site ssl example.com, or wait: the scheduler retries every ten minutes once the name resolves here.
  6. Re-run the verification, this time asking for DNSNow the DNS row is meaningful and the SSL row should have gone from “expected” to passed.
  7. Keep the old server for a weekLong enough for every cached record to expire and for anything you missed to surface while you still have somewhere to look it up.

What happens to the old server

Nothing is installed on it, and nothing is left behind. KLYRN connects over SSH, runs the tools the server already has, streams the result, and deletes any temporary archive it created there. With root it uses cPanel's own packaging tool; without root, a cPanel account can package itself through cPanel's own API, and on a server with no panel at all an ordinary Unix login is enough for the files, the databases and the crontab.

Two details worth knowing before you type a password:

  • The SSH credential exists only for the length of the job and is never written to the database; only the local archive path is stored.
  • Pin the host key with --fingerprint SHA256:…. A key that does not match stops the connection during the handshake, before the password is offered, and the refusal names both fingerprints. On 0.3.5‑beta.1 an unpinned connection trusts whatever key answers; recording the key on the first connection and enforcing it afterwards is built and not yet released. Encrypted private keys are not supported yet.

The old server keeps serving throughout. If the plan looks wrong you have lost an upload and nothing else.

The commands are on Migration. What one source does that the others do not, with the refusals and the rollback for each: DirectAdmin, cPanel/WHM, a Linux server over SSH, another KLYRN server.