How to Restore WordPress from Backup

The exact steps to restore a WordPress site from a mysqldump backup and rclone file backup — whether recovering from accidental deletion, server failure, or migration to a new VPS.

Terminal showing mysql restore command importing a SQL backup file into MariaDB

A backup that has never been tested is a backup you’re not sure works. This article is both the restore procedure and the test.

Run through it on a test server before you need it for real.


Scenario A — Restoring to the Same Server

Use this when recovering from a database issue, corruption, or accidental content deletion while the server and files are still intact.

Step 1 — Download the backup from cloud storage

# From R2
rclone copy r2:wp-backups/db/wordpress_site_2026-06-08_02-00-00.sql.gz \
    /tmp/restore/

# From Google Drive
rclone copy gdrive:wp-backups/db/wordpress_site_2026-06-08_02-00-00.sql.gz \
    /tmp/restore/

Step 2 — Drop and recreate the database

mysql -u root -p
DROP DATABASE wordpress_site;
CREATE DATABASE wordpress_site CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON wordpress_site.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;
exit;

Step 3 — Import the backup

gunzip -c /tmp/restore/wordpress_site_2026-06-08_02-00-00.sql.gz | \
    mysql -u root -p wordpress_site

Step 4 — Verify

mysql -u root -p -e "SELECT COUNT(*) FROM wordpress_site.wp_posts;"

Should return a number matching your post count.


Scenario B — Restoring to a New Server

Use this after a complete server loss — accidental deletion, provider failure, migration. The stack from Parts 3–5 must be set up first.

Prerequisites:

  • New VPS provisioned and configured (Parts 2–3)
  • LEMP stack installed (Part 4)
  • Web root created with correct permissions
  • wp-config.php configured with new database credentials
  • DNS updated to point to new server IP

Step 1 — Restore WordPress files from cloud storage

# Restore wp-content/uploads
rclone sync r2:wp-backups/uploads/yourdomain.com/ \
    /var/www/yourdomain.com/wp-content/uploads/

# Download fresh WordPress core
cd /var/www/yourdomain.com
sudo wget https://wordpress.org/latest.tar.gz
sudo tar -xzf latest.tar.gz
sudo mv wordpress/* .
sudo rm -rf wordpress/ latest.tar.gz

Step 2 — Restore the database

# Download latest database backup
rclone copy r2:wp-backups/db/ /tmp/restore/ \
    --include "wordpress_site_*.sql.gz" \
    --max-age 24h

# Find the most recent file
LATEST=$(ls -t /tmp/restore/*.sql.gz | head -1)

# Import
gunzip -c "$LATEST" | mysql -u root -p wordpress_site

Step 3 — Update wp-config.php if credentials changed

If the new server uses different database credentials, update wp-config.php:

sudo nano /var/www/yourdomain.com/wp-config.php
# Update DB_USER and DB_PASSWORD to match the new database user

Step 4 — Fix permissions

sudo chown -R nginx:nginx /var/www/yourdomain.com/
sudo find /var/www/yourdomain.com/ -type f -exec chmod 644 {} \;
sudo find /var/www/yourdomain.com/ -type d -exec chmod 755 {} \;

Step 5 — Install plugins

Core WordPress files and the database are restored. Plugins in the database reference plugin files that need to be reinstalled:

Log into wp-admin → Plugins → any showing as missing will need reinstallation.

Alternatively, if you backed up wp-content/plugins/ separately, restore from there.


Verify the Restore

# Check Nginx serves the site
curl -I https://yourdomain.com
# Should return 200

# Check WordPress is responding
curl -s https://yourdomain.com | grep "<title>"
# Should show your site title

# Check database post count
mysql -u wp_user -p wordpress_site -e "SELECT COUNT(*) FROM wp_posts WHERE post_status='publish';"

The Time Difference

Without database backups (what happened with rm -rf /):

  • Provision server: 5 minutes
  • Install stack: 2 hours
  • Download files: 30 minutes
  • Rebuild databases from memory/partial exports: 4–6 hours
  • Total: most of a day

With daily mysqldump backups:

  • Provision server: 5 minutes
  • Install stack: 2 hours
  • Restore database: 10 minutes
  • Restore files: 30 minutes
  • Total: under 3 hours

With a Vultr snapshot from the previous week:

  • Restore snapshot: 10 minutes
  • Replay any database changes since snapshot: varies
  • Total: 30 minutes to 1 hour

The combination — daily database backups plus weekly Vultr snapshots — covers all realistic failure scenarios. Part 7 is done.