VorticPanel

Installation

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.

Every word has to appear. ↑ ↓ to move, Enter to open.