Skip to content

Account Backups

A CorePanel backup captures a whole account: its home directory, its databases, its domains and subdomains, its FTP accounts, its mailboxes and its mail routing, plus the account’s own identity and limits. The result is a single .tar archive that can rebuild the account from scratch.

It is, deliberately, the inverse of the cPanel importer: the same idea of a self-describing archive, in the other direction.

ResourceCaptured
Home directoryEvery file the account owns, with ownership and permissions
MySQLEach database, dumped, plus its users and their grants
DomainsPrimary, aliases and addon domains, with their document roots, serving modes, canonical host and web optimizations
SubdomainsWith their document roots, serving modes and their own web optimizations
MailboxesAccounts and their mail
Mail routingEvery forwarder, the domain catch-all and the whole-domain redirect
FTP accounts
ApplicationsEach application’s settings, its environment variables, its data volume and the release it was running
The account itselfuid/gid, home path, PHP version, package reference and every limit

A manifest.json at the root of the archive indexes all of it, so an archive can be inspected — and a restore planned — without unpacking it first.

Backups → Create backup, pick the account, and the job starts in the background. The job list shows progress and, when it finishes, a per-resource report of what was captured and what was not.

From the CLI:

Terminal window
corepanel account backup <username>

Archives are written to /var/lib/corepanel/backups on the server.

On Business, a hosting account can take a backup of itself from the client panel. It is off until you turn it on, in Server → Settings → Client panel, because the archive lands on the panel’s disk rather than inside the account’s quota.

What it does to this page: those jobs appear in the list like any other, marked as the customer’s own. They follow rules of their own, and the reason for each is the same one — the disk they fill is yours, not theirs:

Yours (manual)Yours (scheduled)The customer’s
Kept untilYou delete itYour retention policyThe customer’s next backup but two
How oftenWhenever you likeYour scheduleOnce an hour at most, one at a time
Remote destinationYesYesNo — always local

The rotation is the part worth knowing before you switch it on: a customer’s two most recent archives survive, and a third pushes the oldest out. It bounds what your disk can be asked to hold to roughly twice the size of the accounts whose owners use the button — and it never touches an archive of yours, whichever way you took it.

Downloading is not governed by that switch. A customer can always download any finished backup of their own account, including the ones your schedule produced: the archive is a copy of their own data.

The Schedules tab defines recurring backups.

FieldNotes
NameHow the schedule appears in the list
ScopeA single account, or all accounts on the server
Frequencydaily (02:00), weekly (Sundays 02:00), monthly (1st, 02:00), or a custom five-field cron expression
Retention — keepMaximum number of archives to keep. 0 = no limit
Retention — daysDelete archives older than N days. 0 = no limit
EnabledA disabled schedule stays defined but does not fire

A server-wide schedule runs a bounded number of accounts at a time rather than starting one job per account at once — a full backup is a heavy mysqldump plus a large tarball, and firing hundreds in parallel would take the server down.

Run now executes a schedule immediately, which is the right way to verify one before trusting it.

By default an archive stays on the same disk as the server it protects — which is exactly the failure a backup exists to survive. A destination is where CorePanel copies the finished archive: S3-compatible object storage, or any SSH server over SFTP.

The Destinations tab of the Backups view manages them.

DriverWorks with
S3-compatibleAWS S3, MinIO, Cloudflare R2, Backblaze B2, Wasabi, and Google Cloud Storage through its S3 endpoint
SFTPAny SSH server with a directory you can write to

Adding one asks for the settings the driver needs — bucket and endpoint, or host and remote path — plus its credentials. Two fields are worth understanding:

  • Path-style addressing (S3) puts the bucket in the URL path instead of the hostname. MinIO and most self-hosted gateways need it; AWS does not. Getting it wrong is the usual cause of a destination that connects but cannot find the bucket.
  • Host key (SFTP) pins the server’s identity. Left empty, CorePanel adopts the key it sees on the first successful connection and verifies every later one against it.

Edit changes a destination’s settings in place — a corrected bucket, a new prefix, or rotated credentials. Leave the credential fields empty and the stored ones are kept, so fixing a typo in the endpoint never costs you the keys. The driver itself cannot change: S3 and SFTP are different destinations, not two settings of one.

Editing rather than replacing matters more than it looks. Backup jobs remember which destination they were pushed to by id, so deleting a destination and creating an identical one leaves every archive already stored there orphaned: retention can no longer find it, and those files stay in the bucket — billed — until someone removes them by hand. Rotating S3 keys is an edit, not a re-creation.

Test connection uploads a small probe object, lists it and deletes it again. That is deliberately more than a login check: a destination can accept a connection and still reject writes, and you do not want to discover that on the night you need the backup. The result is stored, so the list shows the last known state of every destination.

Once a destination exists, Create backup and every schedule can point at it. A schedule’s retention then prunes the remote copies too, not just the local ones.

Remote destinations require CorePanel Pro or Business. Listing, disabling and deleting a destination — and restoring an archive back from one — work on every edition, so a lapsed licence never leaves you unable to reach your own backups.

Restore takes an archive and rebuilds the account: system user (with its original uid/gid and home path), files, databases and users, domains, subdomains, mailboxes, mail routing and FTP accounts.

Two options shape the run:

OptionEffect
Dry runReports everything the restore would do, and every conflict it would hit, without writing anything
On conflictabort (default) stops at the first collision; skip restores everything that does not collide and reports the rest

Always dry-run a restore onto a server that already hosts things. A domain name is unique across the whole server, so an existing domain is the most common collision.

A restore ends by scanning the rebuilt account for WordPress installations, so its sites are back in WordPress — not just back on disk — when the job finishes. The archive carries the sites’ files and databases but no catalog of its own, which is why the scan runs rather than being restored from the archive.

The report’s wordpress line says how many installations were cataloged. If it reads skipped, the scan could not run: the sites themselves are unaffected and corepanel wp scan <account> lists them.

Forwarders, the catch-all and the whole-domain redirect are recreated after the mailboxes, in the order they were originally created. Both halves of that matter: a forwarder that keeps a copy in its own mailbox needs that mailbox to be back first, and a forwarder is checked against the ones already present, so replaying the sequence that built the routing is what rebuilds it.

A route that cannot be recreated is reported and skipped, never fatal — the restore has already brought back the account by then. There are two realistic reasons: its domain did not restore (the domain step says why), or a forwarder that delivers into its own mailbox found that mailbox suspended, which is the one state the panel does not let you create either.

Archives taken before CorePanel captured mail routing carry none, and restore without it.

The account’s password — for the panel and for FTP — is preserved when the archive carries a recoverable hash, so the customer’s credentials keep working. When it does not, the account is restored with a random password and the report says a reset is required.

A mailbox or FTP login that was closed when the backup ran comes back closed. Its password is restored with it, so reopening the login later gives the owner back the one they already had — but the restore never reopens it for you, because a login somebody disabled is not something to hand back by surprise on the day of an incident. Backups taken before CorePanel recorded this restore every login active, as they always did.

MySQL users are recreated with their original credentials where the hash can be recovered. A user whose password cannot be recovered is skipped and reported rather than recreated with a random password — recreating it would silently break the application that connects with it.

A failure in one resource does not abort the whole run: it downgrades the job to partial and is recorded in the report. You get an account that mostly came back plus an explicit list of what did not, instead of an all-or-nothing failure.

Backup archives are not deleted when an account is deleted. That is the point of a backup: it must outlive what it describes. Restoring a deleted account is the ordinary restore flow, with no collisions to worry about.

The archive is self-contained, so rebuilding an account elsewhere is just a restore on the other machine. The account’s uid/gid, home path and limits come from the archive, and its hosting package is re-mapped by name if the ID differs on the target.

If both servers share a destination, nothing has to be copied by hand: add the same destination on the new server, list what is stored there, and restore the archive you want.

Terminal window
corepanel backup-destination add offsite --type s3 --endpoint ... --bucket ...
corepanel backup-destination archives offsite
corepanel account restore --dest offsite --remote-key cpbackup-pxdemo-20260802T031500Z-j42.tar --wait

Otherwise, copy the .tar across and restore it as a local file.

The DNS zone is regenerated by the new server, so its records point at the new machine rather than the old one. What is not automatic is the delegation: the domain keeps resolving to the old server until its nameservers or records are changed.

A few things do not travel in the archive today, and are worth planning for: custom DNS records beyond the managed zone, mail forwarders, TLS certificates (Let’s Encrypt reissues them once DNS points at the new server) and application data under /var/opt/userapps.

Backups are written to /var/lib/corepanel/backups on the server itself, unencrypted, and copied to a destination when one is configured. Two consequences worth planning around:

  • Get a copy off the server. A backup on the same disk as the account does not survive the failure it is there to protect against. A destination is the built-in answer; a rsync or rclone cron job is the manual one.
  • Treat archives as sensitive, wherever they land. An archive contains the account’s files, its databases, its mail and the password hashes of its mailboxes and database users. On a destination that means a private bucket and credentials scoped to it — a bucket that is readable by the world publishes all of that.
Account backupWordPress restore point
ScopeThe whole accountOne WordPress instance
ContentsFiles, databases, domains, mail, FTPThat instance’s document root and database
HistoryGoverned by retentionThree per instance
Survives account deletionYesNo
PurposeDisaster recovery, migrationAn undo button for an update

Use restore points around risky updates. Use backups for everything else.