Skip to main content

Backups

The server backs up assets, one at a time, into one backup repository in an S3 bucket, with restic or kopia running in a container. An asset is a home directory, a database, a mailbox, or the panel's own database; a snapshot is one complete copy of an asset at one moment.

Backups live on the command line and the server API; the admin app has no screen for them. Account holders see their own assets, snapshots and restores in their panel: Backups in the account docs covers that side.

The repository​

A repository is an S3 endpoint, a bucket and a path in it, with an access key. Create the bucket first, with a policy that lets the key list the bucket and read, write and delete objects in it:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::<bucket>"
},
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": "arn:aws:s3:::<bucket>/*"
}
]
}

Then register it:

elpanctl backup:repo:create --set-active --type=<restic|kopia> <description> https://<endpoint>/<bucket>/<path> <access-key-id> <access-key-secret>

--type picks the engine; kopia is the default. The engine initialises the repository before anything is saved: a location it refuses (unreachable, wrong keys, a repository already there) stores nothing. Every repository is encrypted with a password the panel generates when it creates it and keeps with the repository.

The server has one active repository; every backup and restore uses it. backup:repo:set-default <id> makes another one active, backup:repo:list and backup:repo:view <id> show them, backup:repo:delete <id> forgets one.

CommandUse it when
backup:repo:edit <id> --uri=... --access-key-id=... --access-key-secret=...The repository moved to another bucket or endpoint, or the keys were replaced. The new location is checked before it is saved; the repository is not initialised again and its password stays the same.
backup:repo:edit <id> --description=...A new description.
backup:repo:init [<id>]Initialise a registered repository that is not initialised yet; defaults to the active one. On an initialised repository it says so and exits 0.
An unreachable repository is slow to fail

The engines retry a failed request for about fifteen minutes before giving up. The panel checks the repository under a short limit before it starts a run, so a dead endpoint fails fast with the engine's reason instead of stalling every asset for a quarter of an hour.

What is backed up​

Each asset has its own interval and retention policy. The panel creates the assets: one for each account's home directory, one for each database and mailbox, and one for its own system database.

AssetPathIntervalKeepsLeaves out
Home directory/home/<account>3 days1 latest, 7 daily, 4 weekly, 6 monthlyvendor/, node_modules/, caches, tmp/ and *.tmp, logs, the trash
DatabaseA dump written to /var/spool/elpan/backup/<id> before each run30 days1 latest, 2 monthly
Domain user (mailbox)The user's mail location3 days1 latest, 7 daily, 4 weeklyDovecot index files, the Spam and Trash folders, Maildir tmp/
System databaseThe panel's own database1 day1 latest, 7 daily, 4 weekly

A successful run sets the asset's next earliest backup one interval ahead. A failed run records the error on the asset and tries again two hours later; backup:asset:list --last-failed lists the assets whose last run failed, and backup:asset:view <uuid> shows one with its error, last run and next earliest backup.

When the thing an asset backs up is gone (a deleted database, a removed mailbox, a purged account), the asset is retired: it is taken off the schedule but kept, so its snapshots stay restorable.

To change one asset:

elpanctl backup:asset:set-interval <uuid> <seconds>
elpanctl backup:asset:set-retention <uuid> --keep-daily=<n> --keep-weekly=<n> --keep-monthly=<n>

The account holder sees these values in the panel but cannot change them.

Run backups​

backup:run backs up every asset whose next earliest backup has passed, the most overdue first, in batches of 50 (--batch-size). --class=<class> (homedirectory, database, emailaccount or systemdatabase) restricts it to one kind of asset, and --dry-run lists what it would do. It checks the repository once before the first backup, exits non-zero when any asset failed, and retires the assets whose subject is gone.

elpanctl backup:run
elpanctl backup:asset:backup <uuid> [<uuid> ...]
No timer ships

Nothing in the packages runs backup:run on a schedule. Run it from a timer or cron job of your own, as root, as often as the shortest interval needs (a day, for the system database).

Retention is applied on demand too: backup:asset:expire <uuid> ... forgets the snapshots outside the asset's policy, and backup:asset:prune <uuid> ... reclaims the space they held.

The panel's telemetry reports the last successful run per asset type, the assets whose last run failed, and the assets more than a day overdue (Telemetry).

Restore an asset​

elpanctl backup:asset:snapshot:list <uuid>
elpanctl backup:asset:snapshot:view <uuid> <identifier>
elpanctl backup:asset:restore <uuid> <identifier>
A restore is in place and complete

backup:asset:restore returns the whole asset to the state of the snapshot: anything written since is gone. For one file, download the snapshot instead.

backup:asset:tar <uuid> <identifier> <output-file> writes a snapshot as a tar archive; --compression (none, gzip, bzip2, xz, zstd) is taken from the file name when not given.

A restore or backup an account holder requests from their panel runs in a background worker as a backup task. A task whose worker died is settled by an hourly sweep after 24 hours of silence, and settled tasks are deleted after 90 days.

Backups and account deletion​

A deleted account's assets are retired, not removed: the last snapshots stay restorable after the account is gone, unless the deletion asked for the backups to go too. The options of account:purge are in Suspend, terminate and delete an account.

The server API​

The repositories, assets and snapshots are also on the Server API, under /api/v1/backup-repositories and the backup endpoints of an account.