Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/sglogger/afrit-backup-manager/archive/refs/heads/main.zipBackups, restores and migrations for the whole WordPress installation: incremental file backups, selectable database tables, encryption, scheduling, retention rules per location, and simultaneous upload to this server, FTP/FTPS, SFTP, Dropbox and OneDrive. Restore files, database, plugins or themes separately, or move the site to a new domain or host.
There is no PRO version. Every feature is free, and will stay that way.
About the name: afrit is Icelandic for "copy", "duplicate" — Icelandic builds its word for a backup from it: öryggisafrit, literally "safety copy". Which is fairly close to the entire job description: keep a good copy, and give it back the moment it is needed. The sibling plugin Vokull Security Center takes its name from Icelandic as well.
This README is the developer manual's front page. The detailed documentation
lives in docs/; the user-facing description is in
readme.txt.
Screens
All screens exist in English and German: screenshots/en,
screenshots/de. They are generated, not hand-made — see
Screenshots.
Design principles
- Never lose a backup to a timeout. Every job runs in resumable steps of a few seconds, driven by loopback requests, WP-Cron and the admin screen. Shared hosting is the baseline, not an edge case.
- Backups are never reachable by URL. Outside the web root where possible, otherwise locked down and probed over HTTP daily. Downloads only through the authenticated admin.
- A failed restore changes nothing. The database is imported into temporary tables and swapped in atomically at the end; files are written to a temporary name and renamed into place.
- One unavailable destination never costs the backup. Destinations are independent; failures are retried, then reported.
- No relay server, no account, no telemetry. OAuth apps belong to the site owner; nothing leaves the site unless a destination was configured.
- WordPress.org rules apply. GPL, no locked features, no bundled translations, Plugin Check clean, every external service documented.
Features at a glance
| Area | What it does | Docs |
|---|---|---|
| Backup | Whole installation (core, plugins, themes, uploads, rest of wp-content) plus database | backup format |
| Incremental | Full + incremental chains; only changed files after the first backup | backup format |
| Files | Clickable folder tree: include/exclude any folder, most specific rule wins; patterns, size limit | architecture |
| Database | Pure-PHP resumable dump, all or selected tables | architecture |
| Destinations | This server, FTP/FTPS, SFTP, Dropbox, OneDrive — simultaneously | storage drivers |
| Scheduling | Files and database separately: every N hours, daily, weekly, monthly | architecture |
| Before updates | Backup of what changes before core/plugin/theme updates | architecture |
| Retention | Counts, GFS, max age, days per location, per-destination override; "Keep" marks exempt chosen backups | architecture |
| Restore | Per component and per table, search & replace, safety backup | restore and migration |
| Migration | Migration keys, shared storage or upload; URL/path/prefix rewriting | restore and migration |
| Encryption | XChaCha20-Poly1305 stream format, PBKDF2 key | backup format |
| Security | Exposure self-test, authenticated downloads, sealed credentials, plugin password | security |
| Reports | Run history with full logs, e-mail reports | architecture |
| WP-CLI | wp afbm backup|restore|list|keep|migrate|prune|rescan|status |
WP-CLI |
Requirements
- WordPress 6.5+, PHP 8.1+
- PHP
zipextension (ZipArchive) for file backups - PHP cURL for the FTP/FTPS destination
- libsodium (bundled with PHP; WordPress ships
sodium_compatas fallback) for encryption
Installation
From the release ZIP: Plugins → Add New → Upload. From source: see
Local development — vendor/ is not tracked and must be
installed with Composer.
Configuration constants
| Constant | Effect |
|---|---|
AFBM_DISABLE_PASSWORD |
true bypasses the plugin password (recovery when it is lost). |
AFBM_DROPBOX_APP_KEY |
App key of the built-in Dropbox app, overriding Storage_Dropbox::PLUGIN_APP_KEY. |
Everything else is a setting in the admin, or a filter.
Local development
Everything runs in Docker; nothing but Docker is needed on the host.
cp docker-compose.yml-example docker-compose.yml
cp .env.example .env
docker compose up -d --build
docker compose exec wpcli wp core install --url=http://localhost:9190 --title="Afrit Dev" \
--admin_user=admin --admin_password=admin123 --admin_email=admin@example.test --skip-email
docker compose exec wpcli wp plugin activate afrit-backup-manager
# Second site, the migration target (table prefix wpt_):
docker compose exec wpcli-target wp core install --url=http://localhost:9192 --title="Afrit Target" \
--admin_user=admin --admin_password=admin123 --admin_email=admin@example.test --skip-email
docker compose exec wpcli-target wp plugin activate afrit-backup-manager
# Dependencies (no local PHP needed):
docker run --rm -u "$(id -u):$(id -g)" -v "$PWD":/app -e COMPOSER_HOME=/tmp/composer composer:2 install
| URL / host | What |
|---|---|
| http://localhost:9190 | Source site (admin / admin123) |
| http://localhost:9192 | Migration target |
| http://localhost:9191 | phpMyAdmin |
| http://localhost:9125 | Mailpit (report e-mails) |
ftp:21, sftp:22 |
Storage test servers (user backup / backup-secret, SFTP folder upload/…) |
Details, including the three dev-only must-use plugins, are in docs/development.md.
Tests and linting
docker run --rm -v "$PWD":/app -w /app php:8.3-cli-alpine php vendor/bin/phpunit --testdox
docker run --rm -v "$PWD":/app -w /app php:8.3-cli-alpine php -d memory_limit=1G vendor/bin/phpcs
dev/screenshots/run.sh smoke # browser smoke test against the Docker site
What is covered where, and the manual end-to-end checklist: docs/testing.md.
Screenshots and icons
dev/screenshots/run.sh # icons, banners, all screens in English and German
dev/screenshots/run.sh icons # icons and banners only
Runs the official Playwright image against the Docker site. The SVG master is
assets/logos/afrit-backup-manager-icon.svg; PNGs and the WordPress.org
banners are rendered from it.
Coding conventions
Same as the sibling plugin Vokull Security Center:
- Namespace
AfritBackupManager;final class Under_Scoreinclass-kebab-case.php. - Prefixes:
AFBM_(constants),afbm_(options, hooks, tables, form fields). - No autoloader in production: the main file
require_onces every class in dependency order. Composer's autoloader is loaded lazily for phpseclib only. - Components are objects with a
register(): voidmethod that only adds hooks. - WordPress Coding Standards (
phpcs.xml.dist), short arrays, tabs, Yoda conditions. - Every deviation is an inline
phpcs:ignorewith the reason, so Plugin Check honours it too. - Comments explain why.
- Logic that can be free of WordPress is (Components, Manifest, File_Index, Encryptor, Search_Replace, Schedule, Retention_Policy, Sql_Importer) — and is unit-tested.
Releasing (maintainer)
- Bump the version in three places: plugin header,
AFBM_VERSION,Stable tagin readme.txt. Add a CHANGELOG.md entry and mirror it into readme.txt. ./package-plugin.shbuildsdist/afrit-backup-manager-<version>.zip(allow-list staging,composer install --no-dev, refuses dev files).- Push to
main:.github/workflows/auto-tag.ymltags, builds the same ZIP and publishes a GitHub release;deploy-to-wordpress-org.ymlsyncs it to SVN.
More in docs/releasing.md.
Translations
English source strings, text domain afrit-backup-manager. No translation
files ship in the ZIP — WordPress.org delivers them from translate.wordpress.org.
The template is languages/afrit-backup-manager.pot; the German translation to
import there is dev/translations/afrit-backup-manager-de_DE.po. See
docs/translations.md.
Privacy
The author collects nothing; the plugin runs on the site owner's server and sends backups only to destinations the owner configures. Full text: PRIVACY.md.
Licence
GPL-2.0-or-later. See LICENSE.txt.







