A backup is only useful if it can be restored. That sounds obvious, but it changes how you should choose backup software, schedule jobs, store credentials, and decide what belongs in a backup.
For a VPS, the goal is normally not to clone every temporary file on the machine. It is to preserve the data and configuration needed to rebuild the service: application files, databases, environment variables, uploads, configuration files, and a record of how the stack is deployed.
This guide compares three excellent free open-source backup tools for Linux servers:
- Restic: simple, encrypted, script-friendly backups to many storage backends.
- BorgBackup: efficient deduplicated backups, particularly good over SSH.
- Kopia: encrypted snapshots with a command-line interface and optional web UI.
All three can protect a VPS properly. The right choice depends less on features and more on where you want to store backups, how comfortable you are with the command line, and how you intend to restore data under pressure.
Start with the 3-2-1 principle
Before selecting a tool, decide where copies will live.
The usual 3-2-1 guidance is:
- Keep three copies of important data.
- Store them on two different storage systems.
- Keep one copy off the primary server or location.
For a small VPS, this might mean:
- The live application data on the VPS.
- Provider snapshots or backups where available.
- An encrypted backup repository in separate object storage, a backup VPS, NAS, or another provider.
Do not treat a backup folder on the same VPS as a backup. It can help with an accidental deletion, but it does not protect against server loss, account compromise, filesystem damage, or a failed disk.
What should a VPS backup include?
The answer depends on the workload, but most production backups need these categories.
Application data
Back up the directory that contains persistent uploads, user content, application state, and mounted Docker volumes. Do not assume source code is enough if the service accepts user uploads.
Databases
Back up a consistent logical dump or use a database-aware backup process. Copying live database files from disk is often unsafe unless the database is stopped or its documentation explicitly supports it.
For PostgreSQL:
pg_dump -Fc your_database > /var/backups/postgres/your_database.dump
For MariaDB or MySQL:
mysqldump --single-transaction --routines --events your_database > /var/backups/mysql/your_database.sql
Configuration and deployment files
Include files such as:
/etc/nginx/or your reverse-proxy configuration.- Docker Compose files and Compose environment files.
- Application configuration stored under
/etc/. - Cron jobs and systemd unit files.
- Firewall configuration, where applicable.
Never casually place production secrets in a public Git repository. A private configuration repository can be useful, but it is not a substitute for an encrypted backup.
A restore note
Keep a short README-restore.md in the repository or in your operations documentation. List the services, data paths, database names, DNS dependencies, and the order required to restore them. A ten-line note written calmly is far more useful than relying on memory during an outage.
Option 1: Restic for encrypted, portable backups
Restic is a strong default for many VPS owners. It encrypts data before it leaves the server, deduplicates snapshots, supports retention policies, and works with local storage, SFTP, S3-compatible object storage, Backblaze B2, and several other backends.
Install and initialise a Restic repository
On Debian or Ubuntu:
sudo apt update
sudo apt install restic
Set a strong repository password in a root-readable file:
sudo install -m 600 /dev/null /root/.restic-password
sudo nano /root/.restic-password
For an SFTP repository, the repository URL may look like this:
export RESTIC_REPOSITORY="sftp:backup@example-backup-host:/srv/restic/my-vps"
export RESTIC_PASSWORD_FILE="/root/.restic-password"
restic init
Run an initial backup:
restic backup \
/etc \
/srv \
/var/lib/docker/volumes \
/var/backups/postgres \
--exclude /var/lib/docker/overlay2 \
--exclude /srv/*/node_modules
The exclusions matter. Back up persistent Docker volumes, not the container image layers that can be downloaded again. Similarly, node_modules can usually be rebuilt from a lockfile, while uploaded content and databases cannot.
Retention and integrity checks
Use a retention policy so the repository does not grow forever:
restic forget --prune \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 12
Run a repository integrity check regularly:
restic check
To restore a snapshot to a safe directory:
restic snapshots
restic restore latest --target /root/restore-test
Inspect the restored files before relying on the system in an emergency.
Automate Restic with systemd
Create /usr/local/sbin/restic-backup:
#!/bin/bash
set -euo pipefail
export RESTIC_REPOSITORY="sftp:backup@example-backup-host:/srv/restic/my-vps"
export RESTIC_PASSWORD_FILE="/root/.restic-password"
pg_dump -Fc your_database > /var/backups/postgres/your_database.dump
restic backup /etc /srv /var/backups/postgres --exclude /srv/*/node_modules
restic forget --prune --keep-daily 7 --keep-weekly 4 --keep-monthly 12
Make it executable:
sudo chmod 700 /usr/local/sbin/restic-backup
Then run it through a systemd service and timer. Timers are generally easier to audit than an untracked cron entry because job status is visible through systemctl and journalctl.
Option 2: BorgBackup for efficient SSH backups
BorgBackup is a mature choice when you control a second Linux server, NAS, or storage box with SSH access. It is known for efficient deduplication and compression, which makes repeated backups of similar data economical.
Install it:
sudo apt update
sudo apt install borgbackup
Initialise an encrypted repository on the backup host:
export BORG_REPO="ssh://backup@example-backup-host/./srv/borg/my-vps"
export BORG_PASSPHRASE="use-a-unique-long-passphrase"
borg init --encryption=repokey-blake2
Create a snapshot:
borg create --stats --compression lz4 \
::'{hostname}-{now:%Y-%m-%d_%H-%M}' \
/etc \
/srv \
/var/backups/postgres \
--exclude /var/lib/docker/overlay2 \
--exclude '**/node_modules'
Apply retention:
borg prune --list \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 12
Check archives periodically:
borg check --verify-data
Restore to a separate path first:
borg list
borg extract ::my-vps-2026-07-13_02-00
Use a dedicated backup SSH key. Restrict it to the backup host and avoid giving it interactive shell access if your environment supports forced commands or repository-only restrictions.
Option 3: Kopia for snapshot visibility and flexible storage
Kopia is useful when you want encrypted, deduplicated snapshots with both command-line and graphical management options. It supports several repository types and can be a good fit for people who want a more visual view of backup history.
The workflow is similar:
- Create an encrypted repository.
- Add one or more source paths.
- Schedule snapshots.
- Define retention.
- Test a restore.
For example, after connecting a repository, you can create a snapshot from the command line:
kopia snapshot create /etc /srv /var/backups/postgres
The exact repository connection command depends on whether you use local storage, SFTP, or an object-storage backend. Keep repository credentials and encryption passwords separate from the server data. If both the backup files and the only copy of the encryption password are lost together, the backup cannot help you.
Docker backups: volumes, databases, and Compose files
Docker makes deployment repeatable, but it also makes it easy to back up the wrong data.
Usually you should preserve:
- The
compose.yamlordocker-compose.ymlfile. - Environment files stored outside the repository.
- Named volumes containing database or application data.
- Database dumps created before the file backup.
- Reverse-proxy configuration and TLS-related configuration.
You generally do not need to back up:
- Pulled container images.
- Build caches.
overlay2layers.- Dependency directories that can be rebuilt from lockfiles.
If a database runs in Docker, run its native dump command inside the container or from a dedicated backup job. For example:
docker exec postgres-db pg_dump -U app -Fc appdb > /var/backups/postgres/appdb.dump
Then include /var/backups/postgres in your Restic, Borg, or Kopia source set.
Test restores, not just backup jobs
Successful backup logs are encouraging but incomplete. At least once a month, restore a recent snapshot into a temporary directory or test VPS and confirm:
- The expected files are present.
- Database dumps can be read or restored.
- Environment files and configuration are available.
- The application can start using the restored data.
- You know where the encryption password is stored.
For a website, this can be as simple as restoring a database and uploads directory on a temporary host. For a bot or API, restore the configuration and database to an isolated test instance and run a health check.
Common backup mistakes
| Mistake | Better approach |
|---|---|
| Backups stored only on the live VPS | Send an encrypted copy to separate storage |
| Copying a live database data directory | Create a database-aware dump or use supported snapshots |
| Backing up Docker layers but not volumes | Preserve named volumes and Compose configuration |
| One giant backup with no retention | Keep a defined daily, weekly and monthly policy |
| Encrypting data but losing the password | Store the password securely outside the VPS |
| Never testing restore | Schedule a recurring restore test |
| A backup job that fails silently | Send logs or alerts on failure |
Choosing a tool
Choose Restic when you want a simple encrypted CLI workflow and flexible remote storage support.
Choose BorgBackup when you have a Linux backup destination over SSH and want excellent deduplication with a proven command-line workflow.
Choose Kopia when snapshot visibility and an optional UI are important alongside encryption and deduplication.
The tool matters less than the operating habits around it: off-server copies, explicit retention, protected credentials, and tested restores.
Backing up a HYEHOST VPS
HYEHOST VPS plans are suitable for self-hosted services, containers, databases, bots, and websites. Use the panel for service controls and recovery access, but keep application-level backups independent of the server itself.
For small projects, a Restic repository in separate storage is often a clean starting point. As your environment grows, a second VPS, dedicated backup storage, or a NAS using BorgBackup can provide more control. The important part is that your backup copy is encrypted, off the primary server, and tested before you need it.
Frequently asked questions
Which open-source backup tool is best for a VPS?
Restic is a strong default for flexible remote storage. BorgBackup is excellent when you control a Linux destination over SSH. Kopia is useful when you value snapshot visibility and optional graphical management.
Should backups stay on the same VPS?
No. Keep at least one encrypted copy outside the primary server so the workload and its only backup cannot disappear in the same failure.
How often should I test a restore?
Test a recent snapshot regularly, ideally each month, and confirm that files, database dumps, configuration and the application startup process are all usable.

