How do I rebuild a server from a Disaster Recovery bundle?
Install the same panel on a new server, install BackupWall, restore the DR bundle with bw-dr-restore, rescan each destination, restore all accounts, then resume backups. BackupWall restores accounts, not the operating system or the panel.
What you need
- A DR bundle of the old server and its passphrase (Set up Disaster Recovery).
- A way to read the DR destination without BackupWall (the S3 console,
aws,rclone,sftp): the destination's credentials are inside the bundle you are about to open. - A BackupWall release at the same build as the old server, or newer.
- On a server with no panel: the unix users of the accounts (name, uid, gid, shell). Save them while the server is alive:
getent passwd <account> ....
1. Prepare the new server
- Install the same panel as before, installed and licensed: cPanel & WHM, DirectAdmin or Plesk, or none. BackupWall restores accounts into a working panel; it does not install the panel. A bundle from one panel type restored onto another keeps the old panel settings and will not work.
- Leave enough disk on
/home(and for MySQL) for every account. A restore does not check free space first. - With no panel, install MySQL or MariaDB with a passwordless local
rootlogin (mysql -uroot -e 'SELECT VERSION();'must print a version).
2. Install BackupWall
Follow Install BackupWall. Do not set anything up in the console afterwards (no destination, no job): the next step replaces BackupWall's database with the old server's. Check curl -s http://127.0.0.1:8087/api/v1/health/live prints {"status":"ok", ...}.
3. Get the DR bundle
Bundles are on the DR destination under dr/<server-id>/, below the destination's path prefix if it has one. Download the newest with your own tool:
aws s3 ls s3://my-bucket/backups/dr/ --recursive | sort | tail -3
aws s3 cp s3://my-bucket/backups/dr/srv-abc123/backupwall-dr-20261111-040000.bwdr .
If you wrote down the bundle's checksum (Settings → Disaster Recovery → Recent exports), keep it. If you fetch by hand, look in both <prefix>/dr/<server>/ and <prefix>dr/<server>/ (older builds wrote the second).
4. Bring back BackupWall's own state
Run these as root (sudo -i first: on AlmaLinux and Rocky, sudo bw-dr-restore may not find the command; or call /usr/local/bin/bw-dr-restore).
systemctl stop backupwall-api backupwall-worker backupwall-download-worker backupwall-beat
bw-dr-restore --bundle backupwall-dr-20261111-040000.bwdr --dry-run # asks the passphrase, writes nothing
bw-dr-restore --bundle backupwall-dr-20261111-040000.bwdr # add --expect-checksum <sha256> if you have it
systemctl start backupwall-api backupwall-worker backupwall-download-worker backupwall-beat
systemctl restart backupwall-watcher
bw-dr-restore puts back the old server's database and master key and keeps this server's own settings (Redis password, panel token, paths, certificate). It moves what was there aside as *.pre-dr-restore-<time>. You do not need to run install.sh again.
Backups are paused. It switches off every active backup job, the DR schedule and every recurring clone, and the nightly cleanup waits too. Every page shows "This server was rebuilt from a DR bundle on <date>. Backups are paused until you resume them." (--no-pause skips this; do not use it unless you know why.)
5. Sign in and check the destinations
Sign in with the old server's admin user and password (the restored database brought them back), not the one the new installer printed.
- Open Destinations and choose Test on each. A pass proves the master key came back.
- Open Backup points: the old server's points are listed.
- Rescan each destination (its card: Rescan destination, then Preview, then Import). The bundle is older than the newest backups, so points made after it are on the destination but not in the restored database. A rescan imports this server's ones as ordinary restorable points marked Imported. Backups of other servers on the same destination are listed and never imported.
6. No panel only: create the unix users
Create each account's unix user with the same uid, gid and shell and no home directory, for example groupadd -g 1001 alice then useradd -u 1001 -g 1001 -s /bin/bash -d /home/alice -M alice. Do not use useradd -m: an account counts as "on this server" when its /home folder exists, and the default is to skip those. With cPanel, DirectAdmin or Plesk, skip this step.
7. Restore all accounts
Open Restore → Restore all accounts, choose a job, a point or a destination, preview, fix what the preview warns about, and queue. See Restore all accounts. Then check a few accounts by hand: open a site, log in to a mailbox, compare a database's row count.
8. Resume backups
When the accounts are back and each destination has been rescanned, choose Resume backups on the banner. It switches back on exactly what the rebuild paused. A schedule whose time passed while paused runs at its next normal time. Take a backup now with Run now and check that it completes. Over the API: GET /server/post-recovery shows the state and POST /server/post-recovery/resume with {"confirm":true} resumes.
9. Afterwards
- Other BackupWall servers linked to this one must pin its new TLS certificate (Settings → Peering).
- The licence sees a rebuilt server as a new machine. Run
python -m app.licensing status, andrebindif needed. See Activate or move your licence. - Set up or confirm DR on the new server (the schedule came back with the bundle), and choose Export now once.
What a rebuild does not cover
BackupWall is a file-level engine. It does not back up or restore the operating system, the control panel itself, its licence, or server-wide settings (WHM tweak settings, EA4 profile, firewall, mail server configuration, hosting packages, PHP versions). There is no bare-metal recovery, and PortWall does not plan a block-level one. Rebuild the OS and panel yourself, then follow this article.
PortWall's 2026-11-11 trial on a server with no panel restored 115 accounts, 38 GB and 55 databases with 0 failures. A complete rebuild on a second server of every panel type has not been rehearsed end to end.
If something goes wrong
| What you see | What to do |
|---|---|
bw-dr-restore: command not found with sudo |
Run it from a root shell (sudo -i), or call /usr/local/bin/bw-dr-restore. |
these services are running |
Stop the four services first (step 4). |
| A destination test fails after the rebuild | The master key did not come back: the bundle had no backupwall.env (a "not restorable" export). Use an older bundle that shows OK. |
| Every account is "Already on this server" (no panel) | The users were made with home directories. Choose Overwrite, or remove the empty folders. |
| Restored files are owned by root | The unix user did not exist. Create it and restore that account again. |
| Backups do not run after the rebuild | That is the pause: choose Resume backups. |
| "Unknown backups found on destination X, cleanup paused" | A backup on X that the database does not know has an unreadable manifest. Nothing is deleted on X meanwhile. Rescan destination lists it with the reason. Another BackupWall server writing to the same folder needs its own path prefix. |
| A rescan says "not imported: ... another install's key" | That backup was made by a server with another master key (or is damaged). It is not imported; cleanup keeps its data. |