WHA Docs
Infrastructure

Backups & Restore

What's backed up, how, and how to restore the database, media or the whole site.

The site's data is protected by a daily offsite backup that follows the 3-2-1 rule: multiple copies, on more than one medium, with at least one kept offsite. It's an external, developer-managed system, so backups run independently of the site and its host.

What's backed up

LayerWhere it livesBackup
DatabaseAmazon RDS (MySQL)Daily offsite backup (3-2-1)
MediaAmazon S3Durable on S3, and included in the daily offsite backup
CodeGitHub + an offsite Git mirrorVersioned in Git; every deploy rebuilds a reproducible artifact, and Heroku keeps prior releases for rollback

Code isn't "backed up" in the same sense: it's in version control, and the deploy artifact is rebuilt from composer.lock on every deploy. Restoring the site's code is just a deploy.

Restoring

The database

A restore is a re-import: take the latest dump and load it into the database.

npm run wp -- db import backup.sql

When restoring into a different environment (for example, production data onto staging), rewrite the URLs after the import:

npm run wp -- search-replace 'https://whallc.com' 'https://staging.whallc.com' --dry-run

Always run search-replace with --dry-run first. See Operations → Search and replace.

Media

Media is served from S3, which is durable, so there's nothing to restore day to day. If an object is lost or deleted, recover it from the daily offsite copy. Because media URLs point at S3, putting the files back in the bucket restores them on the site with no further step.

The whole site (code)

Rebuilding the application is a deploy, not a restore:

  • Roll back a bad release: heroku rollback returns to the previous release. See Operations → Rollback.
  • Rebuild from scratch: deploy master. Heroku builds the artifact from composer.lock, so the result is the same pinned set of code every time. See Deployment.

A full recovery is therefore: redeploy the code, re-import the database dump, and confirm media is in S3 (restoring from the offsite copy only if the bucket itself was lost).

After a restore

  1. Purge the Cloudflare cache and flush the object cache and transients. See Caching.
  2. If the domain changed, confirm search-replace rewrote the URLs.
  3. Check /healthz returns 200.
  4. Spot-check the homepage, the provider listing, and a provider and location detail page.

Who runs it

Backups run daily without intervention and are managed by the developer. For a restore, or to confirm backup status, see Contacts.

On this page