Cross-Server Restore
Cross-server restore is the path you take when the old server is dead, you’re migrating between VPS providers, or you’re cloning production into a staging panel. ProxPanel makes this nearly one-click on V2 backups (v1.0.208+) by embedding the source license key in the backup header so the destination can fetch the right decryption password from the license server.
This page is the operational walk-through. For backup creation and encryption format, see Backups & Recovery.
Why this is tricky in the first place
Section titled “Why this is tricky in the first place”The .proisp.bak file is encrypted with a key derived from the originating server’s DB password, which is itself derived from the originating server’s license. A naive restore on a different server uses the new server’s DB password — and fails with decryption failed because the two passwords are different.
The fix is to identify which license originally encrypted the file, fetch that license’s DB password from the central license server, and decrypt with it.
┌──────────────────┐ ┌──────────────────────┐ ┌──────────────────┐│ Old server │ │ license.proxrad.com │ │ New server ││ license: PROXP-A│ │ │ │ license: PROXP-B││ │ │ PROXP-A → pwd_A │ │ ││ Backup created │ │ PROXP-B → pwd_B │ │ Restore started ││ encrypted_with │ ─────▶ │ │ ◀───── │ reads V2 header:││ pwd_A │ upload│ │ fetch │ LICENSE_KEY=A ││ │ │ │ pwd_A │ ││ │ │ │ ─────▶ │ decrypts with A │└──────────────────┘ └──────────────────────┘ └──────────────────┘V2 (current) — fully automatic
Section titled “V2 (current) — fully automatic”Backups created since v1.0.208 prepend the source license key right after the magic header:
PROXPANEL_ENCRYPTED_BACKUP_V2\nLICENSE_KEY=PROXP-XXXXX-XXXXX-XXXXX-XXXXX\n<binary ciphertext>When you restore, the destination server:
- Reads the first ~200 bytes.
- Sees the V2 magic.
- Extracts
LICENSE_KEY=…(line 2). - Calls
GET https://license.proxrad.com/api/v1/license/backup-passwordwith headerX-License-Key: PROXP-A…. - License server returns
{db_password: "…"}for that license. - Derives the AES key, decrypts, restores into Postgres.
No user input required.
Step-by-step: V2 migration
Section titled “Step-by-step: V2 migration”-
On the old server, create a fresh full backup (Backups → Create Backup) and download the
.proisp.bakfile to your workstation. -
Install ProxPanel on the new server using
curl -sL https://license.proxrad.com/install | bash -s -- NEW_LICENSE_KEY(a new, different license key is fine — V2 doesn’t require matching keys). -
Activate the new panel at least once so it’s recognised by the license server. Verify with
curl -s https://NEW_SERVER/health. -
Upload the backup file via Backups → Upload Backup. The file lands in
/var/backups/proisp/on the new server. -
Click Restore on the uploaded file. Leave the Source License Key field empty — the system auto-detects.
-
Wait for completion. A 30 K-subscriber dump takes 30–90 seconds. The page returns
Restored successfully. -
Update MikroTik RADIUS targets to point to the new server’s IP:
/radius set [find] address=NEW_IP. -
Update DNS for
panel.example.comto the new IP. Customer portals continue to work the moment DNS propagates.
That’s it. The new server now serves the old data and continues to validate against the old license. If you want it to use the new license going forward, see “Re-binding licenses” below.
V1 (legacy) — manual license key entry
Section titled “V1 (legacy) — manual license key entry”If your backup was created before v1.0.208, the header is just:
PROXPANEL_ENCRYPTED_BACKUP_V1\n<binary ciphertext>No license key embedded. On restore you must fill in the Source License Key field manually:
-
Upload the V1 backup to the new server.
-
Click Restore. In the modal, paste the source license key in the “Source License Key” field. (It’s
PROXP-XXXXX-XXXXX-XXXXX-XXXXX, the one used to install the old panel.) -
Click Restore Backup. The destination fetches
pwdfor that license key from the license server and decrypts.
If you don’t have the source license key, contact info@proxrad.com with the file’s timestamp and source server IP — we can look it up in the license database.
API call (programmatic restore)
Section titled “API call (programmatic restore)”# Upload the backupcurl -X POST -H "Authorization: Bearer $TOKEN" \ -F "file=@proisp_full_20260512_140530.proisp.bak" \ https://NEW_PANEL/api/backups/upload
# Restore (V2 — source key auto-detected)curl -X POST -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"source_license_key":""}' \ https://NEW_PANEL/api/backups/proisp_full_20260512_140530.proisp.bak/restore
# Restore (V1 — source key required)curl -X POST -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"source_license_key":"PROXP-OLD-LICENSE-KEY-HERE"}' \ https://NEW_PANEL/api/backups/proisp_full_20260512_140530.proisp.bak/restoreWhat changes on the new server
Section titled “What changes on the new server”After a successful cross-server restore, the database (and so subscribers, services, NAS, FUP counters, transactions, invoices, audit log, settings) is whatever the old server had. But these things on the new server are unchanged:
| Item | Source |
|---|---|
| Subscribers, services, RADIUS data | Restored from backup |
| Settings (timezone, branding, notification creds) | Restored from backup |
LICENSE_KEY in .env | New server’s own |
HARDWARE_ID | New server’s own |
| Frontend logo / uploads | Not restored — needs separate tar -xzvf of /opt/proxpanel/frontend/dist/uploads/ |
| TLS certificates (Let’s Encrypt) | New server’s own |
nginx.conf SSL config | New server’s own (preserved by install) |
Uploads (logos, login background, favicon, customer-portal assets) are stored on the filesystem rather than in Postgres. You need to copy them across separately:
# On old servertar -czvf /tmp/uploads.tar.gz /opt/proxpanel/frontend/dist/uploads/scp /tmp/uploads.tar.gz root@NEW_SERVER:/tmp/
# On new servertar -xzvf /tmp/uploads.tar.gz -C /docker exec proxpanel-frontend nginx -s reload“Recover from Existing Server” wizard
Section titled ““Recover from Existing Server” wizard”For brand-new ProxPanel installs, the Settings → Cluster → Recover from Existing Server wizard automates the whole flow:
-
Install fresh ProxPanel on the new hardware.
-
Settings → Cluster → Recover from Existing Server.
-
Enter the old server’s IP and root password (or SSH key).
-
Click Test Connection. Should return
API/DB/SSHreachable. -
Click Recover Data. Behind the scenes:
- SSHes to the old server.
- Runs
pg_dumpdirectly on the source. - Streams it to the new server.
- Restores into the new Postgres.
- Rsyncs
/opt/proxpanel/frontend/dist/uploads/. - Configures the new server as the new main.
-
Update MikroTik RADIUS IP. Done.
This is the recommended path for DR when the source is still online but going away — it skips the manual download/upload step entirely.
Re-binding licenses
Section titled “Re-binding licenses”After a cross-server restore, the new panel still uses its own license key for validation but holds the old panel’s data. You have two choices:
Keep both licenses (recommended)
The old license stays bound to the old server’s hardware ID. The new license stays bound to the new server’s hardware ID. Each pays per its own activation. Data is on the new server; the old server is decommissioned.
If the old server is truly dead, ask info@proxrad.com to suspend that license so you’re not billed twice.
Migrate the old license to the new server
If you want the same license key to keep working (e.g. a customer-facing license number on contracts), an admin on the license server can re-bind:
# On the license serverdocker exec proxpanel-license-db psql -U proxpanel -d proxpanel_license -c " UPDATE licenses SET hardware_id = NULL WHERE license_key = 'PROXP-OLD-KEY';"Then on the new server, set LICENSE_KEY=PROXP-OLD-KEY in .env, restart the API container, and it’ll re-activate against the new hardware.
The new license you used for the install can then be cancelled or returned to support.
Common pitfalls
Section titled “Common pitfalls”- “License key required in X-License-Key header” (HTTP 400). V1 backup, empty Source License Key field. Fill in the source license key.
- “Invalid license key” (HTTP 404) from
/license/backup-password. Wrong source license key, or that license has been deleted from the license server. - “Database password not found for this license” (HTTP 404). Old license has no stored DB password — happens for installs older than v1.0.166 that never fetched secrets. Contact support.
- “decryption failed - this backup may be from a different installation”. Salt mismatch (pre-v1.0.74 backup), or you entered the wrong source license key. Try the correct key, or rebuild the panel from a more recent backup.
- Schema version mismatch. Restoring a v1.0.300 backup onto a v1.0.510 panel works because GORM auto-migrates new columns on startup. Restoring an OLD panel onto a NEW backup does not — install the same or newer version first.
Permissions
Section titled “Permissions”backups.restore is required to perform a restore. It is destructive — the entire current database is overwritten. Most operators keep this admin-only and never grant it to resellers.
Related pages
Section titled “Related pages”- Backups & Recovery — file format, scheduling, encryption.
- HA Cluster — for ongoing replication rather than ad-hoc restore, use streaming replication.
- Failover — planned migration of a live cluster.
- Updates — version compatibility for restore.