All documentation
  1. Home
  2. Docs
  3. Disaster recovery

Disaster recovery

The question asked when the machine is gone is not “restore this site”. It is “what was on it?”. A bucket full of encrypted archives cannot answer that.

Why a manifest

The thing that knew which accounts existed, which domains pointed where, which PHP version each site ran and which database belonged to which site was the SQLite file on the disk that just died. Every one of those facts is needed before a single byte can be restored, and none of them is inside an encrypted archive named after a timestamp.

So KLYRN writes that knowledge to the same bucket, as a small versioned document. A freshly built machine with the destination credentials and the backup key reads it and says, before restoring anything: here are your sites, here are the accounts they belong to, here is the most recent copy of each, and here is what will happen if you restore them onto this box.

What it holds

<prefix>/_server/recovery.json.enc   the manifest, encrypted
<prefix>/_server/keyinfo.json        a key fingerprint, in the clear

The manifest carries the format version, the KLYRN and database schema versions that wrote it, and a server block identifying the install, so a recovery can tell "restore onto new metal" from "roll this same machine back". Then:

Accounts
Name, uid, home, owner's email, disk limit, whether suspended.
Sites
Domain, type, account, PHP version, document root, www handling, certificate state, every alias and redirect, database names and their users, cron entries, and whether the site is a staging copy of another.
Copies
Up to twenty verified remote backups per site, newest first, named by object prefix.

What it deliberately does not hold, as part of the format rather than as an oversight: database passwords, API tokens, sessions, panel credentials, TLS private keys, and any file or database content. A password in a manifest is a password in a bucket. Certificates are re-issued from Let's Encrypt once DNS points at the new machine, which is simpler than moving private keys through object storage and strictly safer.

It is rewritten after every successful remote backup, so it never lags the copies it describes by more than one backup cycle.

Recovering a server

klyrn recover discover     # what was on the lost server, and what conflicts here
klyrn recover run          # restore every site that has a copy
klyrn recover run --only example.com,shop.example.com
klyrn recover run --overwrite   # replace sites that already exist here

The panel has the same flow under Backups → Recover a server.

  1. Install KLYRN on the new machineThe ordinary one-command install. Nothing special.
  2. Give it the destination and the keyThe same bucket credentials, then klyrn backup key import. If the key is wrong, keyinfo.json names the fingerprint you need.
  3. DiscoverReads the manifest and lists every account and site, each marked restorable or not, and each name that already exists here marked as a conflict.
  4. RunOne fetch-and-restore per site, using the same code path a single-site restore uses. A second restore implementation is a second thing to get wrong on the day it matters most.
  5. Point DNS at the new server, then issue certificatesklyrn dns point <domain> if the provider is connected, then klyrn site ssl <domain>.

What it refuses, and why

No destination configured
There is nothing to read. Configure the backup destination first.
No manifest in the bucket
The server that wrote these backups predates the manifest. The message says so, and says the individual site copies can still be restored one at a time.
Not decryptable
None of this server's keys opens it. The message says to import the key from the old server.
A newer format version
Refused, naming both versions and saying to update KLYRN. Guessing at a format from the future is how a recovery silently restores the wrong thing.
A name that already exists here
Skipped as a conflict unless you ask for overwrite. Nothing on the new machine is replaced by accident.