Manual recovery without the panel
A backup is a folder of plain files, and an offsite copy is the same folder in a bucket. You can restore one with a shell, Docker and rclone, with the panel stopped or gone. When the panel works, restore from it instead: it takes a safety backup first and checks the site afterwards.
What a backup holds
Section titled “What a backup holds”Each backup is a folder <backup root>/<slug>/<YYYYMMDD-HHMMSS>/, timestamped in UTC. The backup
root is /srv/backups unless the server’s location was moved on Backups → Storage.
| File | Content |
|---|---|
db.sql.gz |
A mariadb-dump --single-transaction of the site’s database |
files.tar.gz |
The site’s wordpress/ folder, its config/ folder and site.json |
manifest.json |
The slug, title, domains, dev address, PHP and WordPress versions, locale, database name and user, and the table prefix wp_ |
sha256sums |
The SHA-256 checksums of the two archives |
The names on the server follow from the slug. For Northwind Bakery, slug northwind-bakery:
| Thing | Name |
|---|---|
| Container | wp-northwind-bakery |
| Database | wp_northwind_bakery, the slug with dashes turned into underscores |
| Files | /srv/sites/northwind-bakery/wordpress |
| Database server | the wpl7-mariadb container on the same server |
Restore a site on its own server
Section titled “Restore a site on its own server”Run these as root on the server that holds the site.
-
Go to the backup and check it:
Terminal window cd /srv/backups/northwind-bakery/20261004-030000Terminal window sha256sum -c sha256sums -
Stop the site:
Terminal window docker stop wp-northwind-bakery -
Empty the database. The site’s database user keeps its rights:
Terminal window docker exec wpl7-mariadb sh -c 'exec mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" -e "DROP DATABASE IF EXISTS wp_northwind_bakery; CREATE DATABASE wp_northwind_bakery CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"' -
Import the dump:
Terminal window zcat db.sql.gz | docker exec -i wpl7-mariadb sh -c 'exec mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" wp_northwind_bakery' -
Move the current files aside and unpack the backup’s:
Terminal window mv /srv/sites/northwind-bakery/wordpress /srv/sites/northwind-bakery/wordpress.before-restoreTerminal window tar -xzf files.tar.gz -C /srv/sites/northwind-bakery wordpressTerminal window chown -R 33:33 /srv/sites/northwind-bakery/wordpress -
Start the site:
Terminal window docker start wp-northwind-bakery
Delete wordpress.before-restore once the site works. The database password stays inside the
wpl7-mariadb container, where the commands read it, so it never shows in the process list.
If the site’s address changed since the backup, the database still holds the old one. Replace it the way the panel does:
docker exec -u 33:33 wp-northwind-bakery wp search-replace 'https://northwind-bakery.dev.example.com' 'https://northwindbakery.example' --all-tables --skip-columns=guidRestore from a bucket
Section titled “Restore from a bucket”An offsite copy has the same four files under
<bucket>/<prefix>/<slug>/<YYYYMMDD-HHMMSS>/. The prefix defaults to the panel’s domain. For an
SFTP, FTP or WebDAV destination, the path starts at the remote directory you set instead.
Describe the destination in rclone’s config file, ~/.config/rclone/rclone.conf:
[dest]type = s3provider = AWSaccess_key_id = <access key id>secret_access_key = <secret access key>region = eu-central-1For an S3-compatible vendor, set its provider and endpoint as rclone documents them. Then copy
the backup down and check it:
rclone copy dest:my-backups/panel.example.com/northwind-bakery/20261004-030000 ./restorecd restore && sha256sum -c sha256sumsAny S3 client works too, because the files are stored as they are. Continue with the steps above.
Restore from an encrypted bucket
Section titled “Restore from an encrypted bucket”An encrypted destination stores every name and every byte below <bucket>/<prefix> as
ciphertext. You need both halves of its secret: the passphrase and the salt. The panel shows them
under Backups → Storage, with Passphrase on the destination.
rclone’s config stores both halves obscured. Obscure each one:
rclone obscure 'the-passphrase'rclone obscure 'the-salt'Add a crypt remote to the config, anchored at the bucket and prefix as the panel anchors it:
[vault]type = cryptremote = dest:my-backups/panel.example.comfilename_encryption = standarddirectory_name_encryption = truepassword = <obscured passphrase>password2 = <obscured salt>rclone lsd vault: lists the site names, decrypted. Copy one backup down and check it:
rclone copy vault:northwind-bakery/20261004-030000 ./restorecd restore && sha256sum -c sha256sumsRestore the panel’s database
Section titled “Restore the panel’s database”The nightly panel backup is <backup root>/panel/<YYYYMMDD-HHMMSS>/panel.db.gz, on the panel’s
server, with a manifest.json and sha256sums. It does not contain the panel’s SSH key. Restore
it with the panel stopped:
docker stop wpl7-panelrm -f /srv/panel/panel.db-wal /srv/panel/panel.db-shmgunzip -c /srv/backups/panel/20261004-030000/panel.db.gz > /srv/panel/panel.dbchmod 600 /srv/panel/panel.dbdocker start wpl7-panelThe panel then brings every server in line with that database. FTP logins created after the snapshot are gone, and logins deleted since come back.
Rebuild a site elsewhere
Section titled “Rebuild a site elsewhere”manifest.json has what you need to run the site on any Docker host:
- The official
wordpress:php<version>-apacheimage, with the PHP version from the manifest. - A new database and user, with
db.sql.gzimported into it. - The
wordpress/folder fromfiles.tar.gzas/var/www/html, owned by uid 33. - The database settings as the variables
WORDPRESS_DB_HOST,WORDPRESS_DB_NAME,WORDPRESS_DB_USERandWORDPRESS_DB_PASSWORD, because the site’swp-config.phpreads them from the environment. The table prefix iswp_.
Limits
Section titled “Limits”- The steps restore the files and the database. A site rebuilt on another host runs without what the panel adds: its own mail login, its protection rules and its resource limits.
- The database password of a site is not in its backup. On another host, the site gets a new database user.
- Restoring the panel’s database rolls back everything the panel knows to that night, users and API keys included.