Backing up the controller
Everything the controller knows is in /var/lib/panel:
| File | What it holds |
|---|---|
panel.db (with -wal and -shm next to it while running) |
Every account, server, setting and log |
secret.key |
Decrypts saved credentials, everyone’s two-factor (authenticator) secrets, webhook signing secrets, and the backup encryption keys. Without it, people sign in with a recovery code and set two-factor up again, and each webhook’s secret has to be rotated. |
Automatic backups
You don’t need to set anything up. The installer does it, and every upgrade keeps it going: once an hour, a copy of the database and of secret.key goes to /var/backups/panel. SQLite makes the copy while the panel runs, and each copy is checked before it counts.
In /var/backups/panel |
What it is |
|---|---|
panel-20261005-140312.db |
An hourly copy (the time is UTC). The newest 48 are kept, plus the newest of each of the last 14 days. |
pre-upgrade-0.1.0-20261005-140000.db |
The database just before an upgrade from that version. The last 5 are kept. |
secret.key |
A copy of the key, replaced if the key ever changes. |
See the copies:
ls -lt /var/backups/panel
When the next one is due, and how the last ones went:
systemctl list-timers panel-backup
journalctl -u panel-backup -n 20
Take one now, before a big change for example:
systemctl start panel-backup
The copying is done by /usr/local/sbin/panel-backup, run every hour by /etc/systemd/system/panel-backup.timer (and panel-backup.service next to it), as the panel user. It can only write in /var/lib/panel and /var/backups/panel, and the copies are readable by the panel user and root only.
A copy on another machine
The hourly run can send its copies to another machine over SSH, with rsync. On the controller, as root:
1. Install rsync and give the panel user an SSH key:
apt-get install -y rsync
runuser -u panel -- mkdir -p -m 700 /var/lib/panel/.ssh
runuser -u panel -- ssh-keygen -t ed25519 -N '' -f /var/lib/panel/.ssh/id_ed25519
cat /var/lib/panel/.ssh/id_ed25519.pub
2. On the other machine, add that last line to ~/.ssh/authorized_keys of the user the copies go to (say backup), and make the folder: mkdir -p ~/panel.
3. Back on the controller, connect once so it knows the other machine (answer yes), then say where the copies go:
runuser -u panel -- ssh backup@backup.example.com true
echo 'PANEL_BACKUP_RSYNC=backup@backup.example.com:panel/' > /etc/panel/backup.env
4. Try it:
systemctl start panel-backup && journalctl -u panel-backup -n 5
The last line should say Sent to backup@backup.example.com:panel/. From then on, every hourly copy is sent along. The other machine keeps every copy it gets; delete old ones there when you like.
secret.key isn’t sent with them, on purpose: someone with a database copy and the key can read saved credentials. Copy it off once yourself, to somewhere other than that machine. It doesn’t change.
Restoring
1. Stop the panel and pick a copy:
systemctl stop panel
ls -lt /var/backups/panel
2. Put it back, with the name of the copy you picked:
rm -f /var/lib/panel/panel.db-wal /var/lib/panel/panel.db-shm
runuser -u panel -- install -m 600 /var/backups/panel/panel-20261005-140312.db /var/lib/panel/panel.db
3. If secret.key was lost too, put it back:
runuser -u panel -- install -m 600 /var/backups/panel/secret.key /var/lib/panel/secret.key
The copies are made as the panel user, who owns both folders, so a link someone left in either can’t send root’s copy anywhere else.
4. Start the panel: systemctl start panel.
On a new server, install the panel first with the same --domain, copy the database and secret.key over (with scp), and follow the same steps.
Servers keep running on their nodes whatever happens to the controller. When it’s back, telemetry brings their status up to date.