Wordpress Backup and Restore Plugin
- PHP 92.3%
- JavaScript 5.8%
- CSS 1.9%
| assets | ||
| includes | ||
| installer | ||
| tests | ||
| .gitattributes | ||
| .gitignore | ||
| backinator.php | ||
| README.md | ||
| uninstall.php | ||
Backinator
Backups, restores and migrations for WordPress. It builds full-site archives with a standalone installer, and supports schedules and off-site storage.
What it does
- Backups (Create New): a Setup, Scan and Build wizard. Files and database (or database only) go into one archive plus an
installer.php. - Restore here: the Restore button on any backup. The live site keeps running until the very last step, so a failed restore leaves it untouched.
- Clean restore: after the database swap, the installer deletes files in
wp-admin,wp-includesandwp-contentthat aren't in the archive (plugins, themes and uploads the source didn't have), so the result mirrors the backup. Paths the backup excluded, symlinks,wp-content/backinator-backupsand anything else in the web root are left alone. Untick it in the installer to only overwrite. - Migrate: upload the archive and
installer.phpto an empty folder on any server, openinstaller.php, and enter the new database details. URLs, paths and the table prefix are rewritten safely, including serialized data and Elementor's JSON. - Encryption: on by default. Archives are encrypted with XChaCha20-Poly1305, using a key derived from the site's backup password with Argon2id. The password lives in Settings: keep it in your password manager, because it's the only way to restore off-site copies if the server is gone.
- Schedules: hourly, daily, weekly or monthly, in the site's timezone.
- Storage: S3-compatible services (AWS, Cloudflare R2, Backblaze B2, Wasabi, MinIO), Google Drive, or a folder such as a mounted NAS. Each storage keeps the newest N backups.
- Import: drag in an archive from another site (chunked, so PHP's upload limit doesn't apply), or pull one back from storage.
Backups are stored in wp-content/backinator-backups/, outside the plugin folder, so deleting or updating the plugin never deletes them.
Requirements
PHP 7.4+ with zip, mysqli and sodium (all standard). WordPress 5.8+. Multisite is not supported.
Releasing an update
Sites running Backinator check this repository's releases and offer updates under Dashboard → Updates. A copy that is a git checkout (has .git) never updates itself.
- Bump the version in both places in
backinator.php: theVersion:header andBACKINATOR_VERSION. - Commit and push, then tag:
That's all sites need: they pick up the highest version tag (checked every ~6 hours, or immediately via Settings → Check for updates now).git tag v1.0.1 && git push origin main v1.0.1 - Optional: on git.web9.live, open Releases → New release for the tag to add notes. They're shown as the changelog in WordPress, and a published release takes priority over bare tags.
Forgejo's source archive of the tag is the update package. Files marked export-ignore in .gitattributes are left out of it.
Layout
| Path | Role |
|---|---|
backinator.php |
Bootstrap and hooks |
includes/BackupJob.php |
Resumable backup state machine (scan, DB, files, verify, installer, encrypt, upload) |
includes/ZipWriter.php |
Append-only zip/zip64 writer that resumes across requests |
includes/DbDumper.php |
Resumable, keyset-paged SQL dump |
includes/Runner.php |
Drives jobs: browser polling, loopback chain, inline cron fallback, watchdog |
includes/Storage.php, includes/GDrive.php |
Off-site storage |
includes/Schedules.php |
Cron schedules |
includes/Updater.php |
Updates from git.web9.live releases |
includes/Admin.php, assets/ |
wp-admin UI |
installer/installer.php |
Standalone restore/migration installer (template; config is injected per backup) |