⟵ Все статьи
Читать на:

Website Backup on VPS: How to Set Up Backups and Verify Them

Website Backup on VPS: How to Set Up Backups and Verify Them

On shared hosting, backups are handled by the provider. On a VPS, you handle them yourself. That is the main thing that changes after migration, and it is usually remembered at the worst possible moment: after a failed update, a hack, or an accidental DROP TABLE.

The good news is that setting up backups is about an hour of work done once. Below is a ready-made scheme: what to back up, where to store it, how to automate it, and how to make sure the backup actually works.

What exactly needs to be backed up

Website files, including code, uploaded images, and documents. The database, where all content, orders, and users live. Server configuration, including nginx files, certificates, cron jobs, and systemd unit files: without these, recovery turns into reconfiguration from scratch.

The three-copy rule applies even to a small website: the server itself, a copy on another medium, and a copy in a physically different location. A copy stored on the same server saves you from a code error but not from losing the server entirely.

Step 1. The server where this is done

If you are just migrating, the process is as follows: in the NodexGo control panel, click Create Server, choose a location (your real ping is shown next to each one), a plan, an Ubuntu 24.04 image, and a name, then select a billing period of 1, 3, 6, or 12 months. Within a minute, the IP address and root password will appear in the panel and be sent to your email, and you can connect:

ssh root@server-IP-address

Also consider disk space: backups take up room, and keeping a month of daily database copies directly on the server is common practice. If space runs out, you can always upgrade the plan using the Increase Resources button, and your data stays in place.

NVMe drives and plans with room for backups. Server ready in a minute.

Create a server

Step 2. Database backup

You cannot copy a database like a regular file on a running server, as the result will be a corrupted copy. For MySQL and MariaDB, use mysqldump: the --single-transaction flag takes a consistent snapshot without locking the site.

mysqldump -u root -p --single-transaction --routines --events database_name > /root/backups/db-$(date +%F).sql

For PostgreSQL, the same is done with pg_dump:

pg_dump -U postgres database_name > /root/backups/db-$(date +%F).sql

Dumps compress very well, typically by a factor of five to ten:

gzip /root/backups/db-$(date +%F).sql

Step 3. File backup

Files are conveniently packed into a single archive together with the configuration:

mkdir -p /root/backups
tar -czf /root/backups/files-$(date +%F).tar.gz /var/www /etc/nginx /etc/letsencrypt

If there are many files that change rarely, rsync is a better choice than an archive: it copies only what has changed and runs much faster.

rsync -a --delete /var/www/ /root/backups/www-mirror/

Step 4. Automation with a single script

Manual backups do not work in practice because people stop doing them after a week. Let us put everything into one script:

nano /root/backup.sh
#!/bin/bash
set -euo pipefail

DATE=$(date +%F)
DEST=/root/backups
KEEP_DAYS=14

mkdir -p "$DEST"

# database
mysqldump -u root --single-transaction --routines database_name | gzip > "$DEST/db-$DATE.sql.gz"

# files and configuration
tar -czf "$DEST/files-$DATE.tar.gz" /var/www /etc/nginx /etc/letsencrypt

# remove old backups
find "$DEST" -type f -mtime +$KEEP_DAYS -delete

echo "backup $DATE ok"

To prevent the script from prompting for a database password, store it in the file /root/.my.cnf, accessible only by root:

printf '[client]\nuser=root\npassword=database-password\n' > /root/.my.cnf
chmod 600 /root/.my.cnf

Make the script executable and test it manually:

chmod +x /root/backup.sh
/root/backup.sh
ls -lh /root/backups

Step 5. Scheduled execution

Open the scheduler and add a daily run at 4 AM with logging:

crontab -e
0 4 * * * /root/backup.sh >> /var/log/backup.log 2>&1

After a day, confirm that the job ran successfully:

tail -20 /var/log/backup.log

Step 6. Off-server backup copy

This is the most important step and the one most often skipped. As long as copies reside on the same disk, they will disappear along with it. The simplest option is to pull them to a home computer or a second server on a schedule:

rsync -avz -e ssh root@server-IP-address:/root/backups/ ~/site-backups/

A more robust approach is rclone: it can upload to S3-compatible storage and cloud drives. Configuration is done once through an interactive dialog:

apt install -y rclone
rclone config

After that, sending copies is added to the same script with a single line:

rclone copy /root/backups remote:site-backups --max-age 2d

Step 7. Verify that the backup works

A backup that has never been restored is not really a backup. Verification takes five minutes. Check that the archive is intact and that the dump is not empty:

gzip -t /root/backups/db-*.sql.gz && echo 'archive is intact'
zcat /root/backups/db-2026-08-01.sql.gz | head -20

A real verification means restoring the copy to a separate database and inspecting it:

mysql -u root -e 'CREATE DATABASE restore_test'
zcat /root/backups/db-2026-08-01.sql.gz | mysql -u root restore_test
mysql -u root -e 'SELECT COUNT(*) FROM restore_test.wp_posts'

It is a good idea to run this kind of check once a month, and always after any change to the backup script.

How often to back up

Use a simple question as your guide: how much data loss can you tolerate. A blog can survive losing a day of data, but an online store losing a day of orders means lost revenue, so the database there is backed up every few hours and files once a day.

Also take a manual backup before any risky action: updating the CMS, migrating the database, or changing the PHP version. It takes thirty seconds and can save an entire evening.

Recovery: the order of steps

Database first, then files, then configuration. Restore the dump:

zcat /root/backups/db-2026-08-01.sql.gz | mysql -u root database_name

Restore the files:

tar -xzf /root/backups/files-2026-08-01.tar.gz -C /

If the server fails to boot or SSH access is lost, the server card in the NodexGo panel includes a VNC web console that lets you log into the system without a network connection. As a last resort, there is a Reinstall OS button next to it: a clean system is installed in a couple of minutes, and the site is brought back up from backups using this same guide.

In brief

Back up the database, files, and configuration. Combine everything into one script. Run it daily via cron. Store copies in at least two places, one of which is off the server. Verify by restoring once a month. Backups set up once take about an hour and pay for themselves on the very first bad day.

Need a second server for storing backups? The entry-level plan is more than enough for that.

View plans

Мы используем файлы cookie: необходимые — для входа в аккаунт и языка интерфейса, аналитические — чтобы понимать, какими страницами пользуются. Сторонних рекламных систем у нас нет. Подробнее