Create, verify and restore backups
Where: Admin → System → Maintenance → Backups & restore
Before you start
A database-only archive does not include uploaded bytes. A full backup includes the file scope identified by the screen. Without “empty each table first”, matching IDs are updated and unrelated existing rows remain; with it, records missing from the backup are lost. A rollback also discards newer changes within the restored scope.
Step by step
- Choose a backup folder outside the public web root. Review database-only versus full backup scope.
- Write a full backup before an upgrade/import and use Verify on the archive.
- Download a copy and keep it away from the server.
- For a restore choose the intended archive/version/date; verify first. Decide deliberately whether to empty each table before writing.
- Restore on staging first where possible, then confirm members, content, media, settings and the restored version.
Settings and behaviour
A database-only archive does not include uploaded bytes. A full backup includes the file scope identified by the screen. Without “empty each table first”, matching IDs are updated and unrelated existing rows remain; with it, records missing from the backup are lost. A rollback also discards newer changes within the restored scope.
Offsite S3-compatible storage has its own enablement, endpoint/bucket/region/access credentials and prefix. Test the connection, upload an archive and verify/read it back. Local archives are not an off-host backup. Schedule the exact printed CLI command in your hosting panel; the example schedule is nightly at 03:00 in the scheduler’s timezone, not an assumed UTC setting. Retention applies to the configured archive store.
Where archives are kept
| A relative path is inside the board's own folder; an absolute one can be anywhere the host lets PHP write, which is the safer answer. | Control | What to enter / effect |
|---|---|---|
| Backup folder | Default storage/backups. Point it outside the web root if this server ignores .htaccess (nginx does), because an archive is a complete copy of the database. Initial default: storage/backups. |
|
| Keep at most (archives) | 0 keeps every archive forever. Applied after each new one is written, newest kept first. Initial default: 10. |
|
| Never keep one older than (days) | 0 turns the age rule off. A copy that is past either rule is removed; offsite copies are never removed by this — they are listed on the screen and deleted deliberately. Initial default: 30. |
The offsite target (S3-compatible)
| Any endpoint that speaks S3: AWS, Cloudflare R2, Backblaze B2, MinIO, Wasabi, DigitalOcean Spaces. Certificates are verified in both shapes; if a self-hosted endpoint uses a self-signed certificate, fix the certificate rather than this board. | Control | What to enter / effect |
|---|---|---|
| Copy archives offsite | Switched on, every archive can be copied to the bucket from the list above — and the cron command below copies each new one automatically with --offsite. Initial default: 0. |
|
| Endpoint | The bucket's own endpoint, with the scheme. AWS is https://s3..amazonaws.com; R2 and MinIO endpoints are the account's or the server's address. Initial default: empty. |
|
| Region | It is part of the signature, so a wrong region looks exactly like a wrong key. Most non-AWS providers accept auto or us-east-1. Initial default: us-east-1. |
|
| Bucket | Initial default: empty. | |
| Prefix inside the bucket | Two boards can share a bucket without seeing each other's archives. Leave it empty to use the bucket root. Initial default: forovanta. |
|
| Addressing | Choices: Path-style (/bucket/key) — MinIO, R2, most self-hosted; Virtual-host (bucket.host/key) — AWS's default. Initial default: 1. |
|
| Access key | Read from S3_ACCESS_KEY in the environment first, if the host has one. | |
| Secret key | Read from S3_SECRET_KEY first. Never shown again once saved. | |
| Server-side encryption | Choices: None; AES-256 (SSE-S3); AWS KMS (SSE-KMS). Initial default: none. |
|
| KMS key id | Only used with AWS KMS. Empty means the bucket's default key. Initial default: empty. |
Check the result
Restore a copied archive to staging and open actual uploaded files. A valid checksum is necessary but not a substitute for a recovery drill.
Common questions and troubleshooting
Archive accessible by URL: move storage outside the web root; nginx may ignore .htaccess. S3 fails: compare region, endpoint, bucket and environment credential precedence. JSON export restored but files absent: JSON contains rows, not all file bytes.
