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.
| Command | Use 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. |
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.
| Asset | Path | Interval | Keeps | Leaves out |
|---|---|---|---|---|
| Home directory | /home/<account> | 3 days | 1 latest, 7 daily, 4 weekly, 6 monthly | vendor/, node_modules/, caches, tmp/ and *.tmp, logs, the trash |
| Database | A dump written to /var/spool/elpan/backup/<id> before each run | 30 days | 1 latest, 2 monthly | |
| Domain user (mailbox) | The user's mail location | 3 days | 1 latest, 7 daily, 4 weekly | Dovecot index files, the Spam and Trash folders, Maildir tmp/ |
| System database | The panel's own database | 1 day | 1 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> ...]
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>
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.