Skip to content
Data and operations

VPS Backup and Recovery: Build a Restore Plan

Plan consistent VPS backups, protect credentials and test recovery. Use Restic examples to check a separate copy and measure your application restore process.

ServerQ Editorial Team11 min read

A backup file is useful only if it can help restore the application you need. A complete VPS recovery plan includes the database, uploaded files, configuration, secrets and the software version that can read them. Copying the source code alone may leave the most valuable data behind.

This guide turns that requirement into a practical plan: decide how much recent data can be lost, keep a protected copy outside the VPS and rehearse the restore. Restic examples illustrate an encrypted repository and a separate restore target. They describe work you operate; a VPS purchase alone does not establish that application backups or recovery are included.

What this guide helps you do

  • Set recovery-point and recovery-time objectives for the application.
  • Prepare a consistent backup containing the files, database and required keys.
  • Restore into an isolated environment and measure whether the application works.
Scope

A self-managed Linux VPS with application files and a database. The examples use Restic and a MariaDB database; adapt names, permissions and paths to your own environment.

Before you start
  • An inventory of the application, data, secrets and deployment version.
  • A separate backup server or supported storage account with sufficient space.
  • A tested access method and a way to retain repository credentials without the original VPS.
  • An isolated place to test recovery without sending real messages, payments or workflows.

1. Decide what a successful recovery means

A recovery-point objective, or RPO, describes the amount of recent change you are prepared to lose. A recovery-time objective, or RTO, describes the target time to restore the service. These are planning objectives, not a purchased guarantee. A daily job may leave roughly a day of changes after its last successful backup exposed; unnoticed failures can make that gap much larger.

Include rebuilding the environment, downloading data, restoring secrets, changing traffic and validating the application in the recovery time. If the objective cannot tolerate those steps being improvised, document or automate them and test the result before an incident.

What has to come back?
ApplicationRecovery data to account for
WordPress siteDatabase, uploads, themes/plugins or a reproducible deployment, and required configuration.
Online shopThe same data plus a consistent view of orders and payment-side effects.
n8nWorkflows, database, required user directory, configuration and credential encryption key.
APIPrimary database, uploaded files, secrets and the deployed application version.

2. Build an inventory before choosing a backup tool

  • Persistent application data and volumes.
  • A consistent database export or a database-supported physical backup.
  • Web server, process manager and deployment configuration.
  • Application secrets and encryption keys needed after restoration.
  • The application version or image digest and the order in which components start.

Keep the backup repository password somewhere that remains accessible when the VPS is lost. Storing its only copy inside the encrypted backup defeats recovery. Restrict access to repository credentials and application secrets as carefully as production access.

An archive on the same VPS disk may be useful staging space, but it is not an independent copy against loss of that VPS or disk. Plan a separate protected destination and understand who can delete or alter it. If a compromised production server can erase every backup, encryption alone does not solve the problem.

The recoverable chain
  1. 01Consistent database
  2. 02Files and required keys
  3. 03Encrypted independent copy
  4. 04Isolated restore rehearsal

A successful step does not prove the next one: repository integrity and application recovery both need checking.

3. Prepare and verify the repository access

The following example assumes a Restic installation appropriate for your distribution and version. An Ubuntu package installation is shown for an environment you administer; it is not a statement that a particular OS image is included in a VPS plan. Read the package and Restic documentation before applying it.

The SFTP host backup.example is a placeholder for a separate server you control. Replace the account, hostname and writable path. Verify the SSH host key and access before initialising a repository; do not disable host verification to get past a connection error.

Example package installation and administrative shell
sudo apt update
sudo apt install restic nano
sudo -i

The next example runs in that administrative shell. Enter a unique repository password with your editor; do not place the password itself in a command line or shell history. Keep an independent secured record of it.

Prepare a new encrypted SFTP repository
umask 077
touch /root/restic-password
chmod 600 /root/restic-password
nano /root/restic-password
export RESTIC_PASSWORD_FILE=/root/restic-password
export RESTIC_REPOSITORY="sftp:backupuser@backup.example:/srv/restic/serverq"
restic init
restic snapshots

Use init only to create a new repository. Use snapshots to check access to an existing repository. The SSH credentials must be available to the account running the backup. These environment variables last only in this shell; a scheduled job needs the same configuration supplied securely and explicitly.

4. Stop if a required database export fails

The example below exports a MariaDB database named wordpress before backing up the application files and staging directory. --single-transaction applies to transactional tables such as InnoDB; it is not a universal consistency guarantee for every storage engine or concurrent schema change. Avoid updates that alter tables during the export.

If the database and files must represent the same application moment, arrange an appropriate maintenance window, write pause or application-supported consistent backup method. A successful file copy cannot repair a database export that failed earlier.

Example export followed by a file backup
install -d -m 0700 /root/backup-staging
if mariadb-dump --single-transaction --routines --events wordpress > /root/backup-staging/wordpress.sql.tmp; then
  mv /root/backup-staging/wordpress.sql.tmp /root/backup-staging/wordpress.sql
else
  echo "Database export failed; backup stopped." >&2
  exit 1
fi
restic backup /var/www/wordpress /etc/nginx /root/backup-staging
restic snapshots
restic check

restic check validates repository structure. Reading every data pack with restic check --read-data adds a stronger data-reading check, but takes time and can incur transfer usage with a remote repository. Size that work around the data and storage provider’s terms; a scheduled task is not evidence of a completed backup.

5. Restore into a separate target and verify the application

Restore files into a temporary destination
RESTORE_DIR=$(mktemp -d /var/tmp/serverq-restore.XXXXXX)
restic restore latest --target "$RESTORE_DIR"
find "$RESTORE_DIR" -maxdepth 3 -type d
restic check --read-data

Review snapshots and choose the intended recovery point. latest is convenient for a rehearsal, but the newest successful backup can also contain a recent mistake. In an incident, select the snapshot that matches the recovery objective. Do not automatically copy the restored directory over the running production application.

  1. Inspect critical files and compare expected counts or checksums where appropriate.
  2. Import the database into a separate test database, never over the live one during rehearsal.
  3. Start the matching application version with the required secrets in an isolated environment.
  4. Disable or replace production email, payments, webhooks and scheduled tasks.
  5. Verify login, a representative read/write operation and a media or file retrieval.
  6. Record the elapsed recovery time, missing steps and the data point recovered.

For n8n, a restored database without the correct encryption key may leave saved credentials unusable. For WordPress, missing uploads can leave pages loading while images are broken. Verify the business function you actually need, not only a process status or a successful Restic exit code.

6. Review retention, access and cost together

Preview a retention policy without deleting snapshots
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --dry-run

This is an example retention distribution, not a legal or operational recommendation for every business. Inspect the dry-run output, the grouping of snapshots and the independent copies before adopting a deletion policy. Reclaiming repository storage with prune is a separate operation that deletes data; it should be planned and reviewed.

Budget for the repository, restore traffic, staging space and administration. Allow room on the VPS for temporary exports and logs while keeping the independent copy elsewhere. Document emergency access to the password and review who can read or delete the backups. Repeat the recovery rehearsal after a material application, database or deployment change.

Review scope

The Restic init, backup, check --read-data and restore sequence was exercised with the official Restic 0.19.1 binary in a temporary local fixture on 30 September 2026. Three restored files matched their originals byte for byte. This validates that limited local sequence, not SFTP, MariaDB consistency, a full fresh-VPS installation or your application recovery. The shell examples are also syntax checked; test the complete process in your own isolated environment.

Official references

Check the project’s current documentation for version and configuration details.