• Home
  • Cloud VPS
    • Hong Kong VPS
    • US VPS
  • Dedicated Servers
    • Hong Kong Servers
    • US Servers
    • Singapore Servers
    • Japan Servers
  • Company
    • Contact Us
    • Blog
logo logo
  • Home
  • Cloud VPS
    • Hong Kong VPS
    • US VPS
  • Dedicated Servers
    • Hong Kong Servers
    • US Servers
    • Singapore Servers
    • Japan Servers
  • Company
    • Contact Us
    • Blog
ENEN
  • 简体简体
  • 繁體繁體
Client Area

VPS Snapshot and Backup Strategy: Protect Your Hong Kong VPS Data (2026)

August 1, 2026

Most server failures are survivable — if you have recent backups. Most data loss events are catastrophic — if you don’t. A Hong Kong VPS running production workloads needs a layered backup strategy that covers both rapid recovery from common failures (accidental deletion, configuration errors) and disaster recovery from severe events (hardware failure, ransomware, data centre incident). This guide designs a complete, automated backup system.


The 3-2-1 Backup Rule

The industry standard backup framework:

  • 3 copies of your data
  • 2 different storage media/locations
  • 1 copy off-site (geographically separate from your VPS)

Applied to a Hong Kong VPS: primary data on the VPS NVMe (copy 1), daily snapshots in Server.HK’s storage system (copy 2), and automated off-site backups to Cloudflare R2 or Backblaze B2 (copy 3 — geographically separate).


Layer 1: VPS Snapshots

VPS snapshots capture the entire disk state at a point in time — including OS, configuration, and application files. They enable restoring a server to a known-good state within minutes.

When to Take Snapshots

  • Before any significant system change (OS upgrade, major config change, new software install)
  • Before applying security patches that might affect application compatibility
  • Weekly automated snapshots as a baseline recovery point
<code"># Via Server.HK control panel:
# VPS Management → Snapshots → Take Snapshot
# Name the snapshot descriptively: "pre-php82-upgrade-2026-07-15"

# Via API (if available):
# curl -X POST https://api.server.hk/v1/vps/INSTANCE_ID/snapshot \
#   -H "Authorization: Bearer API_TOKEN" \
#   -d '{"name": "weekly-backup-2026-07-15"}'

Limitations of snapshots: they capture a point-in-time state and are stored within the same infrastructure. They protect against accidental misconfiguration but not data centre-level events. They do not replace off-site backups for databases with frequently changing data.


Layer 2: Automated Database Backups

Databases change constantly — a weekly snapshot misses all data written since the last snapshot. Database-level backups (logical dumps) provide granular, frequent recovery points.

PostgreSQL Automated Backup

<code">cat > /opt/backup/pg-backup.sh << 'EOF' #!/bin/bash set -e DATE=$(date +%Y-%m-%d_%H%M%S) BACKUP_DIR="/opt/backups/postgres" RETENTION_DAYS=7 mkdir -p $BACKUP_DIR # Dump all databases with compression sudo -u postgres pg_dumpall \ --clean \ --if-exists \ | gzip -9 > $BACKUP_DIR/pg_all_$DATE.sql.gz

# Verify the backup is readable
gunzip -t $BACKUP_DIR/pg_all_$DATE.sql.gz || {
  echo "BACKUP VERIFICATION FAILED: $DATE" | \
    mail -s "PG Backup Error" admin@yourdomain.com
  exit 1
}

echo "Backup size: $(du -sh $BACKUP_DIR/pg_all_$DATE.sql.gz | cut -f1)"

# Remove backups older than retention period
find $BACKUP_DIR -name "pg_all_*.sql.gz" -mtime +$RETENTION_DAYS -delete

echo "PostgreSQL backup complete: $DATE"
EOF
chmod +x /opt/backup/pg-backup.sh

MySQL Automated Backup

<code">cat > /opt/backup/mysql-backup.sh << 'EOF' #!/bin/bash DATE=$(date +%Y-%m-%d_%H%M%S) BACKUP_DIR="/opt/backups/mysql" MYSQL_USER="backup_user" MYSQL_PASS="BackupUserPassword!" mkdir -p $BACKUP_DIR # Dump each database separately (easier to restore individual DBs) mysql -u $MYSQL_USER -p$MYSQL_PASS -e "SHOW DATABASES;" | \ grep -Ev "(Database|information_schema|performance_schema|mysql|sys)" | \ while read DB; do mysqldump \ -u $MYSQL_USER -p$MYSQL_PASS \ --single-transaction \ --quick \ --routines \ --triggers \ $DB | gzip -9 > $BACKUP_DIR/${DB}_$DATE.sql.gz
    echo "Backed up: $DB"
  done

find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
echo "MySQL backup complete: $DATE"
EOF
chmod +x /opt/backup/mysql-backup.sh

# Create read-only MySQL backup user
mysql -u root -p -e "
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'BackupUserPassword!';
GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON *.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;"

Schedule Database Backups

<code">crontab -e
# Add:
# PostgreSQL — every 4 hours
0 */4 * * * /opt/backup/pg-backup.sh >> /var/log/pg-backup.log 2>&1

# MySQL — every 4 hours offset by 2 hours
0 2,6,10,14,18,22 * * * /opt/backup/mysql-backup.sh >> /var/log/mysql-backup.log 2>&1

Layer 3: File System Backups

<code">cat > /opt/backup/files-backup.sh << 'EOF' #!/bin/bash DATE=$(date +%Y-%m-%d_%H%M%S) BACKUP_DIR="/opt/backups/files" mkdir -p $BACKUP_DIR # Backup critical directories BACKUP_PATHS=( "/var/www" # Web application files "/etc/nginx" # Nginx configuration "/etc/letsencrypt" # SSL certificates "/opt" # Self-hosted application data "/home" # User home directories ) tar czf $BACKUP_DIR/files_$DATE.tar.gz \ --exclude='/var/www/*/node_modules' \ --exclude='/var/www/*/.git' \ --exclude='/opt/backups' \ "${BACKUP_PATHS[@]}" 2>/dev/null

echo "Files backup size: $(du -sh $BACKUP_DIR/files_$DATE.tar.gz | cut -f1)"
find $BACKUP_DIR -name "files_*.tar.gz" -mtime +3 -delete
EOF
chmod +x /opt/backup/files-backup.sh

# Schedule: daily at 1am
crontab -l | { cat; echo "0 1 * * * /opt/backup/files-backup.sh >> /var/log/files-backup.log 2>&1"; } | crontab -

Layer 4: Off-Site Backup to Cloudflare R2

Cloudflare R2 is the ideal off-site backup destination: zero egress fees (no cost to read backups), S3-compatible API, and global availability.

<code"># Install rclone (S3-compatible sync tool)
curl https://rclone.org/install.sh | bash

# Configure rclone for Cloudflare R2
cat > ~/.config/rclone/rclone.conf << 'EOF'
[r2]
type = s3
provider = Cloudflare
access_key_id = YOUR_R2_ACCESS_KEY
secret_access_key = YOUR_R2_SECRET_KEY
endpoint = https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com
acl = private
EOF

# Create R2 bucket: hk-vps-backups (via Cloudflare dashboard)

# Test connection
rclone ls r2:hk-vps-backups
<code">cat > /opt/backup/offsite-sync.sh << 'EOF' #!/bin/bash LOG="/var/log/offsite-backup.log" echo "--- Off-site sync started: $(date) ---" >> $LOG

# Sync all local backups to R2
rclone sync /opt/backups/ r2:hk-vps-backups/ \
  --progress \
  --log-file=$LOG \
  --log-level INFO \
  --transfers 4 \
  --checksum

# Verify at least one recent backup exists in R2
LATEST=$(rclone ls r2:hk-vps-backups/postgres/ | tail -1)
if [ -z "$LATEST" ]; then
  echo "WARNING: No backups found in R2!" | mail -s "Backup Alert" admin@yourdomain.com
fi

echo "--- Off-site sync complete: $(date) ---" >> $LOG
EOF
chmod +x /opt/backup/offsite-sync.sh

# Schedule: sync to R2 after local backups complete
crontab -l | { cat; echo "30 1 * * * /opt/backup/offsite-sync.sh"; } | crontab -

Layer 5: Incremental Backup with Restic

For large file collections, rsync copies everything on first run. Restic is a modern backup tool that deduplicates data, encrypts backups, and sends only changed blocks — dramatically reducing backup size and transfer time:

<code">apt install -y restic

# Initialise Restic repository in R2
export AWS_ACCESS_KEY_ID="YOUR_R2_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="YOUR_R2_SECRET_KEY"
export RESTIC_REPOSITORY="s3:https://YOUR_ACCOUNT.r2.cloudflarestorage.com/hk-vps-restic"
export RESTIC_PASSWORD="STRONG_ENCRYPTION_PASSPHRASE"

restic init

# First backup
restic backup /var/www /etc /opt --exclude /opt/backups

# Subsequent backups (only changed data sent)
restic backup /var/www /etc /opt --exclude /opt/backups

# List snapshots
restic snapshots

# Schedule incremental backups every 6 hours
crontab -l | { cat; echo "0 */6 * * * /usr/bin/restic backup /var/www /etc /opt --exclude /opt/backups >> /var/log/restic.log 2>&1"; } | crontab -

# Auto-prune: keep 7 daily, 4 weekly, 3 monthly snapshots
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 3 --prune

Recovery Testing (Critical — Most Skipped Step)

A backup strategy you have never tested is not a backup strategy — it is an assumption. Test recovery quarterly:

<code"># Test 1: Database restore to a separate test database
gunzip -c /opt/backups/postgres/pg_all_2026-07-15_030000.sql.gz | \
  sudo -u postgres psql -d postgres -c "CREATE DATABASE restore_test;"
gunzip -c /opt/backups/postgres/pg_all_2026-07-15_030000.sql.gz | \
  sudo -u postgres psql -d restore_test

# Verify row counts
sudo -u postgres psql -d restore_test -c "SELECT COUNT(*) FROM your_main_table;"

# Compare with production
sudo -u postgres psql -d production_db -c "SELECT COUNT(*) FROM your_main_table;"

# Test 2: File restore
tar xzf /opt/backups/files/files_2026-07-15.tar.gz \
  -C /tmp/restore-test/ \
  var/www/yourdomain/wp-config.php

diff /tmp/restore-test/var/www/yourdomain/wp-config.php \
     /var/www/yourdomain/wp-config.php

# Test 3: R2 restore (simulate off-site recovery)
rclone copy r2:hk-vps-backups/postgres/ /tmp/r2-restore-test/
ls -la /tmp/r2-restore-test/

echo "Recovery test complete. Document results and any issues found."

Monitoring Backup Health

<code">cat > /opt/backup/verify-backups.sh << 'EOF' #!/bin/bash ERRORS=0 # Check PostgreSQL backup is recent (less than 5 hours old) PG_LATEST=$(find /opt/backups/postgres -name "*.sql.gz" -mmin -300 | wc -l) [ $PG_LATEST -eq 0 ] && { echo "ALERT: No recent PG backup"; ERRORS=$((ERRORS+1)); } # Check backup is non-zero size PG_SIZE=$(find /opt/backups/postgres -name "*.sql.gz" -mmin -300 -size +100k | wc -l) [ $PG_SIZE -eq 0 ] && { echo "ALERT: PG backup too small (may be empty)"; ERRORS=$((ERRORS+1)); } # Check R2 sync (at least one file updated in last 26 hours) R2_RECENT=$(rclone ls r2:hk-vps-backups/ --max-age 26h 2>/dev/null | wc -l)
[ $R2_RECENT -eq 0 ] && { echo "ALERT: R2 sync may be failing"; ERRORS=$((ERRORS+1)); }

if [ $ERRORS -gt 0 ]; then
  echo "BACKUP HEALTH CHECK FAILED: $ERRORS issues" | \
    mail -s "⚠️ Backup Alert: HK VPS" admin@yourdomain.com
else
  echo "Backup health check passed: $(date)"
fi
EOF
chmod +x /opt/backup/verify-backups.sh

# Run health check daily at 8am (after nightly backups complete)
crontab -l | { cat; echo "0 8 * * * /opt/backup/verify-backups.sh"; } | crontab -

Conclusion

A complete backup strategy for your Hong Kong VPS combines four layers: VPS snapshots for rapid rollback, automated database dumps every 4 hours for minimal data loss window, daily file system archives, and off-site sync to Cloudflare R2 for geographic redundancy. The strategy is only as strong as your last successful recovery test — schedule quarterly restoration drills to verify backups actually work before you need them under pressure.

Protect your data: Browse Server.HK Hong Kong VPS plans — all plans support the snapshot and backup strategies described in this guide.

Leave a Reply

You must be logged in to post a comment.

Recent Posts

  • Hong Kong VPS vs Cloudflare Workers: Which for Asia-Pacific APIs? (2026)
  • How to Self-Host Gitea on Hong Kong VPS: Private Git Server (2026)
  • WooCommerce for China Market on Hong Kong VPS: Sell Cross-Border in 2026
  • Game Server on Hong Kong VPS: CS2, Valheim, and Minecraft for Asia (2026)
  • Linux Kernel and Sysctl Hardening for Hong Kong VPS Security (2026)

Recent Comments

  1. Hong Kong VPS Uptime and SLA: What 99.9% Uptime Really Means for Your Business (2026) - Server.HK on How to Monitor Your Hong Kong VPS: Uptime, Performance, and Alert Setup Guide (2026)
  2. Best Hong Kong VPS Providers in 2026: Compared by Speed, Routing, and Value - Server.HK on How to Migrate Your Website to a Hong Kong VPS: Zero-Downtime Transfer Guide (2026)
  3. vibramycin injection on How to Choose the Right Hong Kong VPS Plan: A Buyer’s Guide for 2026
  4. allopurinol for gout on CN2 GIA vs BGP vs CN2 GT: What’s the Real Difference for China Connectivity?
  5. antibiotics online purchase on How to Set Up a WordPress Site on a Hong Kong VPS with aaPanel (Step-by-Step 2026)

Knowledge Base

Access detailed guides, tutorials, and resources.

Live Chat

Get instant help 24/7 from our support team.

Send Ticket

Our team typically responds within 10 minutes.

logo
Alipay Cc-paypal Cc-stripe Cc-visa Cc-mastercard Bitcoin
Cloud VPS
  • Hong Kong VPS
  • US VPS
Dedicated Servers
  • Hong Kong Servers
  • US Servers
  • Singapore Servers
  • Japan Servers
More
  • Contact Us
  • Blog
  • Legal
© 2026 Server.HK | Hosting Limited, Hong Kong | Company Registration No. 77008912
Telegram
Telegram @ServerHKBot