Restore on a new VPS
Use this guide when the old VPS is lost, broken into or being replaced, and you want the panel, the projects and the email back on a new VPS. It relies on the external copy of the backups (Cloudflare R2 or another S3-compatible storage). Backups kept only on the old VPS disappear with it. Installing for the first time, with nothing to bring over? Follow the step-by-step guide instead.
Most of the time goes to waiting for DNS and for projects to be published again. If the old VPS still runs, keep it until the last step.
What you need before you start
Section titled “What you need before you start”Keep all of this outside the VPS (a password manager, for example). You cannot get it from a server you no longer have.
| What | Where it comes from | If you lost it |
|---|---|---|
| Backup password | The recovery kit you downloaded in Settings → Backups → External copy encryption. The panel also shows it under View password, but only on a panel you can still sign in to. | There is no way around it: without the password, nobody can open the external copies. |
| Storage endpoint and bucket | The recovery kit lists the bucket and the endpoint. | In Cloudflare: R2 → your bucket → Settings → S3 API. |
| Storage access keys (Access Key ID and Secret Access Key) | You saw them once, when you created the token on Cloudflare. They are not in the kit. | Create a new R2 API token for the same bucket (Step-by-step guide, Part 2, Step 6.1). Old files stay readable. The keys you type in step 3 stay in use after the panel is restored from the screen (see step 5). |
| Domain access | Your DNS provider or registrar. | Recover it with the registrar. |
| Provider access | The new VPS provider’s dashboard (to set the PTR and unblock port 25). | — |
What is restored and what is not
Section titled “What is restored and what is not”| Comes back | Does not come back (you redo it) |
|---|---|
| Panel: administrator accounts and two-factor authentication, registered projects, settings, notification settings, panel domain and the keys that encrypt the secrets (project variables, tokens). | The operating system and its hardening: user, SSH key, firewall. Run the installation and the security wizard on the new VPS. |
Backup settings: schedule, frequency, number of copies and the backup password. The storage address and keys are the exception: they stay the ones you typed on this VPS. This holds when you restore from the screen. With restaurar-painel.sh, the whole backup settings file comes back, old keys included (see step 5). | Anything that was not checked in the project’s Backups tab, and files written outside volumes. |
| Projects: the databases and folders that were checked in each project’s Backups tab. Projects from GitHub are deployed again from the repository. For projects created by upload or from a folder on the server, the code comes back from the backup into the project’s source folder, and then the project is deployed. | DNS records, the PTR and the provider’s firewall. They point to the old IP. |
| Email: mailboxes, messages, accounts, rules and DKIM keys, and the webmail settings. | TLS certificates when you restore from the VPS copy or from an external copy without encryption: they are issued again, once DNS points to the new VPS. |
| HTTPS certificates and the Let’s Encrypt account (Caddy): they come back when you restore the encrypted external copy of the panel. A certificate that is still valid is used as it is (no new issuance, so the weekly Let’s Encrypt limit is not spent); one that has already expired is issued again by Caddy on its own. | |
| The email IP reputation: a new IP starts with none. | |
| The code of a project from GitHub as of the backup date: it comes from the repository’s current branch. |
Step by step
Section titled “Step by step”Do steps 2 to 8 without a long pause. The old panel is stopped in step 2 and the services only come back as you restore them.
1. Prepare the new VPS
Section titled “1. Prepare the new VPS”Follow the installation guide from Step 1 to Step 8 and finish the setup wizard, including the Security step. The restore needs a panel you are signed in to, so create a temporary administrator account when the wizard asks for it. The restore replaces it with the old accounts.
If the old VPS used another projects folder, install with the same one (./scripts/install.sh --projects-dir=<folder>, see Operations). Otherwise projects created by upload or from a folder on the server fail in step 7 with “fica fora da pasta de projetos”.
Do not start the mail server on the new VPS before step 8, even though the “Get the panel ready” checklist on the Dashboard suggests it. The scheduled email backup would send an empty mail server to _email/, count as a finished backup and, since the container would already exist, the email would not enter the hold after the panel is restored.
The new panel has the backup schedule on and runs at 03:00 even with no storage connected. That is harmless: the copy stays on the VPS only and does not count as a panel backup for the protection described in step 3, which only considers a backup already sent to the storage. You can install on one day and connect the storage on another.
Check that ports 80 and 443 are open at the provider, and port 25 if you will use email (see Step-by-step guide, Part 2, Step 4.1).
2. Make a final backup and stop the old panel
Section titled “2. Make a final backup and stop the old panel”Skip this step if the old VPS is gone. Otherwise, on the old panel, in this order:
-
In Settings → Backups, click Back up now in the Panel card and in the Email card.
-
Open each project, go to its Backups tab and click Back up now.
-
Wait until every backup shows “external copy verified” under Latest backups. Write down the date and time of the panel and email backups.
-
Only then, stop the old panel, so that two servers do not write to the same bucket (the restored panel brings the same backup schedule back):
Terminal window cd /opt/tws-panel && sudo docker compose stop
From this moment, nothing written or received on the old VPS reaches the new one, until the DNS points to it.
3. Connect the same storage
Section titled “3. Connect the same storage”In the new panel, open Settings → Backups. In External storage, type the same endpoint, bucket and access keys the old VPS used. Region: auto.
Click Test and save.
What to check: “Connection tested and saved” appears.
4. Enter the backup password
Section titled “4. Enter the backup password”Still in Settings → Backups, find the Restore from another server card and click Get started.
- Step 1 of the card shows the connected bucket.
- In step 2, type the backup password from the kit and click Check and use.
What to check: the card accepts the password. If it says it cannot verify it because the check file is missing, you can click Use this password anyway. If it says the password does not open the backups, check the kit again.
5. Restore the panel first
Section titled “5. Restore the panel first”- In step 3, click See what’s in the storage.
- In the Panel block, click Restore the panel.
- Choose the date of the last backup of the old VPS, the one you wrote down in step 2. Do not
assume that the first date in the list is the right one. Confirm by typing the word the screen shows (in code font, with a copy button):
panelwith the English interface,painelwith the Portuguese one. It is the literal word, not the panel domain or name. - Wait. The panel restarts by itself.
What to check: open the new VPS address again (https://203-0-113-10.sslip.io, with the new IP)
and sign in with the old administrator username and password, plus the two-factor code from the old
phone. Go back to Settings → Backups → Restore from another server.
If you already pointed the panel domain’s A record to the new IP and the old panel had access by IP
turned off, the …sslip.io address does not open (the access stays off because the domain points to
this VPS). In that case, sign in at the panel domain.
If the panel does not open at all, restore it from a file instead:
cd /opt/tws-panel && sudo ./scripts/restaurar-painel.sh /root/ARQUIVO.7z (see
Operations). That path skips the adjustments above, so the next two warnings apply
only to it. It also does not hold the schedules (see the final checks). With the encrypted
external copy, the script also puts the certificates and the Let’s Encrypt account back into the
paas_caddy_data volume (without deleting or overwriting what Caddy already has, readable by root only; a backup with a link or special file is refused) and leaves
a marker so the panel makes Caddy reload when it starts. If that fails, it warns and the panel
restore carries on.
6. Point the DNS to the new IP
Section titled “6. Point the DNS to the new IP”Do this while the projects are restored, because DNS takes time to spread. For each domain, edit the A record to the new VPS IP (on Cloudflare, gray cloud, “DNS only”). That includes the panel domain and every project domain. Lower the TTL beforehand if you can.
7. Restore the projects
Section titled “7. Restore the projects”In the Projects block of the card, click Restore next to each project.
- A project shown as “Not registered here: restore the panel first” means step 5 did not finish.
- Choose the date and confirm by typing the project name.
- On a new VPS the project has no containers. Keep Deploy from GitHub before restoring checked
(the box also serves projects that do not come from GitHub). The panel deploys the project and
then puts the databases and folders back. This can take several minutes per project, and the panel
waits up to 45 minutes.
- Project from GitHub: the panel deploys it again from its repository.
- Project created by upload or from a folder on the server: the panel first puts the code from
the backup back into the project’s source folder (the one in the project’s configuration) and
then deploys. That folder must be inside the projects folder of the new VPS
(
PAAS_PROJECTS_DIR, default/opt/tws-projects), without a symbolic link pointing outside it, and the panel user (10001) must be able to write in the projects folder, where the source folder is created. In a project created by upload, the.envthat the panel generated does not come back (the panel generates a new one at deploy); a.envwritten by the project’s owner does. - The source folder already exists on the new VPS with files in it: it stays as it is, nothing is overwritten, and the restore record warns about it. The deploy uses what is already there. To use the code from the backup instead, rename or empty that folder before you click Restore. Doing it afterwards does not help: in a project created by upload, a new restore puts the code back only in the panel’s working copy, and the next deploy fails without the source folder.
What to check: each project opens at its domain and the data is there. The Certificates page shows the project’s domain as Valid. If you restored the panel’s encrypted external copy, the certificates that were still valid come back with it and the panel makes Caddy reload them when it starts (within about 2 minutes; the restore record shows the “Devolver os certificados” step); only what had already expired is issued again. Without them (the VPS copy, or an external copy without encryption), the certificate fails until the DNS from step 6 points to the new IP. Use Try issuing now on that page after that.
8. Restore the email last
Section titled “8. Restore the email last”- In the card, click Restore email, choose the date of the email backup you wrote down in step 2 and confirm by typing the literal word the screen shows (not your email address):
emailwith the English interface,e-mailwith the Portuguese one. If the restore ends with the notice “O servidor de e-mail ainda não existe nesta VPS: abra a página E-mail e clique em Iniciar” (the mail server does not exist on this VPS yet: open the Email page and click Start; this notice comes from the server and is still in Portuguese), open Email and click Start server. It starts with the restored data. - Update the DNS (Email page → the domain → DNS checklist):
- the A record of
mail.send.example.comto the new IP; - the SPF record, which contains the old IP (
ip4:): copy the new value from the checklist; - MX, DKIM and DMARC do not change, because the names and the keys came back.
- the A record of
- Ask the provider to set the PTR of the new IP to
mail.send.example.com. - Check that outbound port 25 is open (Step-by-step guide, Part 2, Step 4.1).
If the restore ends with the notice “Os dados do webmail voltaram, mas o webmail não está rodando nesta VPS” (a server message: the webmail data came back, but webmail is not running here), the webmail was on in the old panel: after the mail server starts, use the amber notice on the Dashboard or Email → Webmail → Enable webmail.
Domains and mailboxes come back to the list by themselves. The panel shows the domains and mailboxes in its own records, not the mail server’s list. So at the end of the email restore the panel reads what the mail server brought back and registers what was missing (a server notice, in Portuguese: “Cadastrei 2 domínios e 4 caixas no painel”, meaning it registered 2 domains and 4 mailboxes). Nothing is turned on and what was already registered does not change. Two consequences: the registered mailboxes have no password known to the panel (the server never hands it over), so use Change password on a mailbox before sending from it; and the domains’ DNS shows as not verified until you click Verify now. If the mail server did not exist on the VPS yet, or the restore warned it could not register them, open Email and click Sync with the mail server (safe to repeat: it never duplicates anything). If the mail server refuses the panel (different admin password), the panel tries once to fix it by itself (rewrites the configuration and restarts the mail server, without deleting data) and reads again; it shows an error only if that does not help, and then the Email screen itself offers Repair now.
The postmaster@ and project mailbox passwords are realigned. After restoring the email, the server gives each mailbox back with the password it had in the backup, while the panel (which created postmaster@ with a password of its own) keeps using its own: sending notifications and the test email failed with 535 5.7.8 Authentication credentials invalid. So the end of the restore and the Sync with the mail server button check the password of postmaster@ and of project mailboxes and reapply the one the panel stores on those that differ (the notice says “Realinhei a senha de N caixas”, meaning it realigned the password of N mailboxes). This is safe because, for those mailboxes, the panel is the source of truth. The panel compares the server’s password with the one it stores and only rewrites the ones that differ; if they already matched, there is no notice. Note: if you changed the password of a project mailbox (or of postmaster@) directly in webmail, that change is undone: for these mailboxes the panel’s password wins, and the right way to change it is Change password in the panel. It does not touch regular user mailboxes (you may have changed the password in webmail) or mailboxes whose password the panel does not know, and it restarts nothing. If one fails, the others carry on and the notice lists the failed ones: click Sync again or use Change password on the mailbox.
What to check: click Verify now until you reach 6/6 OK, send a test email (Step 4.7 of Part 2 of the step-by-step guide), and see Valid in the email certificate card. Send slowly at first: the new IP has no reputation yet.
Final checks
Section titled “Final checks”- The panel opens at its domain with a padlock, and sign-in and two-factor authentication work.
- Certificates shows every address as Valid.
- Every project opens and has its data.
- The schedules are back. After the panel is restored, the automatic backup of the projects and
of the email stays on hold until the data of each one comes back. The hold shows in
Settings → Backups and in the project’s Backups tab, as a message that starts with “Em
pausa” (a server message, in Portuguese), in place of “Next: …”. After you restore each project
and the email, check that the message is gone. A project created after the restore is not held,
and the hold ends by itself after 7 days. If you restored the panel with
restaurar-painel.sh, there is no hold: the old schedule comes back as it was, and it can try to back up a project that has no containers yet. - Do not leave projects waiting. The scheduled backup of a project that still has no containers fails with “Nenhum container do projeto encontrado” (a server message), with a notification. The one of a project that is deployed but whose data has not come back yet can send a backup without the data. Restore the projects soon after the panel.
- Email: the DNS checklist is 6/6, the test email arrives, and a mailbox can sign in to the webmail.
- In Settings → Backups, the Panel card has Automatic backup on checked. If you turned it off as extra care in step 3, turn it on again: the restore brings the old schedule back only when the backup has the backup settings, and an old backup without them leaves the schedule as it was.
- Settings → Time zone shows the time zone you want. Backups run at 03:00 in the VPS time zone.
- Run Back up now on the panel and see “external copy verified”. Then run a project backup.
- If Security shows differences from the old server, update the baseline with Update baseline snapshot, now that the new VPS is hardened.
- Turn the old VPS off for good only now, and delete its DNS leftovers.
If something fails
Section titled “If something fails”-
Wrong password: the card does not accept it. Check the kit again. For a backup made before a password change, the restore window has a link, Was this backup made before a password change? where you type the password in use when that backup was made.
-
The download fails in step 7 or 8: the token may be revoked or wrong. Go to Settings → Backups → External storage → Edit, type the keys again and click Test and save. If you restored the panel with
restaurar-painel.sh, this is also the effect of the old keys that came back (see the warning in step 5). -
“A pasta do código deste projeto (…) fica fora da pasta de projetos desta VPS” (a server message: the project’s code folder is outside this VPS’s projects folder): the panel does not write outside the projects folder. Put the code inside it, with no symbolic link pointing outside, and register the path again in the project’s configuration.
-
“A pasta do código (…) já existe nesta VPS e tem arquivos: ficou como está, nada foi sobrescrito” (a server message: the code folder already exists with files and was left as it is): the deploy uses what is already there. If you want the code from the backup, rename or empty the source folder before clicking Restore, never afterwards (see step 7).
-
“Stalwart: You have to authenticate first” or “O painel não conseguiu autenticar no servidor de e-mail” when changing a mailbox password (or any mail action): the mail server’s admin password lives in two places, the panel’s settings and the running mail server’s own configuration. Restoring the email brings back the old server’s configuration; restoring the panel brings back the old panel’s password. If they differ, every panel call to the mail server is refused. After a restore the panel checks this by itself and, if it can, rewrites the configuration with the panel’s password and restarts the mail server (no data is deleted). If you still see the error, the amber notice on the Dashboard has Repair now (restarts the mail server for a few seconds). Manual way out: Email, stop the mail server and start it again with Start server; that rewrites the configuration with the panel’s password. Do this after both restores, and before creating or changing mailboxes. Sync with the mail server also tries this repair once by itself; if you still see “O painel tentou regravar a configuração e reiniciar” (the panel tried to rewrite the configuration and restart), the error already says that was tried. To find the cause without printing the password, run the command below on the VPS, which only answers “iguais” (equal), “diferentes” (different) or “não deu para ler (rode com sudo?)” (it could not read one of the passwords: run with sudo and check the container names; if equal, the password matches and the problem is elsewhere: see
sudo docker logs paas-stalwart --tail 50; if different, stop and start the mail server in Email):Terminal window # compares the mail server admin password with the panel one; prints only "iguais" (equal), "diferentes" (different) or "não deu para ler (rode com sudo?)" (could not read, run with sudo?), never the passworda=$(sudo docker cp paas-stalwart:/opt/stalwart-mail/etc/config.toml - 2>/dev/null | tar -xO 2>/dev/null | sed -n 's/^secret = "\(.*\)"$/\1/p' | tr -d '\n')b=$(sudo docker exec tws-panel node -e "process.stdout.write(JSON.parse(require('fs').readFileSync('/data/mail/mail.json','utf8')).adminSecret)" 2>/dev/null)if [ -z "$a" ] || [ -z "$b" ]; then echo "não deu para ler (rode com sudo?)"; elif [ "$a" = "$b" ]; then echo iguais; else echo diferentes; fi -
A restore fails halfway: the panel keeps the previous state in
/data/backups/_painel/antes-da-restauracao/and undoes a failed panel swap by itself. Read the error in Latest backups and run the step again. -
No access to the panel at all: restore the panel from a downloaded file with
restaurar-painel.sh, or open the.7zby hand with 7-Zip. The kit explains both.