Skip to content

Backup and restore

A backup is the one thing that cannot be regenerated: the interface private keys and every customer's credentials. Lose those and every customer has to be reissued. The binary, the packages, the certificate — all replaceable. This is not. Treat the archive like a password file.

What is in it

One .tar.gz, holding:

  • wui.db — a consistent SQLite snapshot (VACUUM INTO, not a raw copy that can be caught mid-write). Only in backups from a SQLite panel.
  • wui-export.json — every table as JSON, written through the schema. In every backup, whichever engine. This is the copy that crosses engines and versions: a column a newer panel added is left at its default, a column it dropped is ignored.
  • Everything else in /var/lib/wui — OpenVPN's PKI and server files, generated profiles — except the backups themselves and SQLite's write-ahead sidecars.

Taking one

WhereHow
The panelSettings → Backup → Back up now, or download any listed archive
On a scheduleSettings → Backup: interval and how many to keep; written to /var/backups/wui
The terminalw-ui backup → 1, or wui backup create (with the panel's environment; the menu supplies it)
Telegramthe bot's backup command sends the archive to the admin chat
Uninstalla last copy is written to /root/wui-last-copy-<date>.tar.gz before anything is removed

Restoring

A restore never unpacks over the live data. The archive is checked end to end, a copy of what is there now is taken first, the files are staged beside the data directory, and the next start applies them — the only moment nothing has the database open.

  • From the panel: Settings → Backup → Restore on a listed archive, or Upload one from another server. The panel restarts itself.
  • From the terminal: w-ui backup → 2, give the path. Or wui backup restore FILE, then systemctl restart wui.

By default this server's own addresses — what the tunnels tell customers to connect to — are kept over the archive's. The usual reason to restore on another machine is that the first one is gone, and its address with it. Cloning one machine onto another and wanting the archive's addresses is --move-addresses on the command line, or the checkbox in the panel.

Across engines and versions

Backup fromRestoring intoWhat happens
SQLiteSQLitethe snapshot file is put back — an exact copy
SQLitePostgreSQLthe JSON dump is loaded into PostgreSQL, ids kept, sequences moved past them
PostgreSQLPostgreSQLthe JSON dump is loaded
PostgreSQLSQLitethe JSON dump is loaded into a fresh SQLite file
an older W-UIa newer onethe schema is migrated first, then the data lands in it
a newer W-UIan older onerefused with a clear message when the dump's format is newer than the panel understands; update the panel first

So the database choice at install is not final: install with SQLite, and when the customer count grows, take a backup, re-run the installer with --db postgres and restore it.

Where things are

PathWhat
/var/backups/wui/scheduled backups and the panel's own, with retention; outside the data directory so a restore cannot clobber them and an uninstall leaves them
/var/lib/wui/.restore-pending/a staged restore, applied and removed at the next start
/var/lib/wui/.restore-import.jsona dump waiting to be loaded, for a cross-engine restore; removed once loaded, kept as .failed if it could not be
/root/wui-last-copy-*.tar.gzthe copy an uninstall leaves

Released under the AGPL-3.0 License.