How do I read my backups without BackupWall?
Use bw-extract, a single Python file that reads a destination directly, read-only, and writes plain files, database dumps and mail. It needs no BackupWall database, services or panel, only Python 3.9 or newer, and the master key if the job was encrypted.
What bw-extract is
Your backups do not depend on BackupWall being installed or working. If the server is gone, the console will not start, or you want your data somewhere else, bw-extract reads a destination directly:
- No BackupWall database, no queue, no services, no panel.
- One Python file, Python 3.9 or newer. It ships in the release as
backend/scripts/bw-extract.py; an installed server has it asbw-extract(/usr/local/bin/bw-extract). - Read-only: it never writes, renames or deletes anything on the destination.
- The format it reads is documented, so a backup stays readable without the tool.
- Memory stays small whatever the size of the backup: everything is streamed.
On a BackupWall server run bw-extract --help. Anywhere else, copy the one file and run python3 bw-extract.py.
What else it needs
| Case | Needs |
|---|---|
| zstd-compressed objects (almost every backup) | the zstandard module, or the zstd command (dnf install zstd or apt install zstd) |
| The job had Encrypt backup data on | the cryptography module (dnf install python3-cryptography or apt install python3-cryptography) |
| S3, Wasabi, B2, GCS (HMAC) | nothing (a built-in client); boto3 is used when installed |
| SFTP | the paramiko module (pip install paramiko), or mount the server with sshfs and use --local |
Google Drive, OneDrive and native Google Cloud Storage destinations: copy the BackupWall folder or bucket prefix to a local disk with rclone, then use --local.
Point it at the destination
| Destination | Options |
|---|---|
| Local directory | --local /var/lib/backupwall/backups (the destination's root path) |
| S3 / Wasabi / B2 / MinIO | --s3 BUCKET --prefix 'PREFIX' --endpoint URL --region REGION --s3-credentials keys.json |
| GCS through an HMAC key | --s3 BUCKET --prefix 'PREFIX' --endpoint https://storage.googleapis.com --s3-credentials hmac.json |
| SFTP | --sftp user@host[:port] --sftp-path /remote/path --ssh-key ~/.ssh/id_ed25519 |
Use --prefix exactly as it is set on the destination; on S3 the prefix is used verbatim. --s3-credentials takes a JSON file (access_key_id and secret_access_key), AWS_ACCESS_KEY_ID= lines, or two lines (key id, then secret); or set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. SFTP checks the host key against known_hosts; a password goes in --sftp-password-file or BW_SFTP_PASSWORD.
Encrypted backups: give it the master key
If the job had Encrypt backup data on, you need the master key of the server that made the backup. Either:
--key-file /etc/backupwall/backupwall.env(the old server's file, or any file holdingMASTER_ENCRYPTION_KEY_B64=..., or just the key), or--dr-bundle backupwall-dr-....bwdr(from the destination underdr/<server>/) and its passphrase:--passphrase-file FILE,BW_DR_PASSPHRASE, or it asks.
Without the key an encrypted backup cannot be read by anyone, PortWall included.
Find, look and extract
D="--local /var/lib/backupwall/backups" # or the S3 / SFTP options
bw-extract $D list-points # every point: id, date, accounts, files, size
bw-extract $D list-accounts latest -l # accounts of the newest point
bw-extract $D ls 8505c302 alice public_html # a directory of alice's backup
bw-extract $D extract 8505c302 alice --to /root/restore/alice
bw-extract $D extract 8505c302 alice public_html/wp-content --to /root/out
bw-extract $D extract-db 8505c302 alice alice_wp --to /root/alice_wp.sql.gz
bw-extract $D extras 8505c302 alice --to /root/alice-extras
bw-extract $D verify 8505c302 --deep
- A point is its id, a unique start of it, or
latest. extractrestores files with their mode, mtime, symlinks and directories, and as root their owner (by name, when the user exists on the machine). It writes into an empty directory unless you pass--overwrite, never through a symlink and never into the destination itself. Every object is checked against its hash. A damaged file is reported and not written (--forcewrites it anyway for salvage).extract-dbwrites the dump as stored:.sql.gzfrommysqldump | gzip, or a MongoDBmongodump --archive --gzipfile. Load one withgunzip -c alice_wp.sql.gz | mysql alice_wp.extraswrites DNS zone files, SSL certificates and keys, the crontab, FTP and database-user records, each mailbox as a Maildir tar, and the cPanel account archive (cpmove-<user>.tar.gz, for/scripts/restorepkg). It holds private keys and password hashes: keep it private.verifychecks every object is there;--deepreads everything back (it downloads the whole point).- Exit codes: 0 all good, 1 something failed or is damaged, 2 wrong usage or a missing key, 3 the destination cannot be read.
What it does not do
It does not import databases, recreate panel accounts or send mail. It gives you the files. To restore into a panel, install BackupWall (or use bw-dr-restore with a DR bundle) and restore from the console. Which job made a point, and whether it was completed or partial, lives in BackupWall's database, not on the destination.