I've been putting this off since basically forever. Techpad turns fifteen this coming November and up until about three weeks ago my entire backup strategy was "the host probably backs it up, right." Not a strategy. A hope.
What finally moved me was dumb and small, the way these things usually are. I was messing around in the database trying to fix a broken category count (long story, involves a plugin I installed in 2019 and never removed) and I ran an UPDATE without a WHERE clause. You know the one. Every post on the site got shoved into the same category for about four minutes until I noticed the front page looked wrong and panicked. I had a backup, technically, but it was eleven days old and lived in a folder on my old laptop that I hadn't opened since March. That's not a backup, that's a fossil.
So I spent a Saturday actually fixing this properly, and since a few people have asked how techpad is hosted these days I figured I'd write it up.
What I actually set up
The goal was simple: back up the database and the uploads folder, do it automatically, and put a copy somewhere that isn't the same box the site lives on. If your server dies, a backup sitting on that same server dies with it. Sounds obvious written down. Took me fifteen years to internalize it.
I ended up with restic doing the heavy lifting. It's a command-line backup tool that handles encryption and dedup for you, so your backup archive doesn't balloon every time you run it, only the changed bytes do. The whole setup is maybe twenty lines:
# dump the db
mysqldump -u techpad -p"$DB_PASS" techpad_db > /tmp/techpad.sql
# back up the sql dump plus the uploads dir
restic backup /tmp/techpad.sql /var/www/techpad/wp-content/uploads \
--repo /mnt/backup-remote/techpad-restic \
--password-file /root/.restic-pass
# keep 7 daily, 4 weekly, 6 monthly, prune the rest
restic forget --repo /mnt/backup-remote/techpad-restic \
--password-file /root/.restic-pass \
--keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
That /mnt/backup-remote bit is mounted via rclone to a separate object storage bucket, not the VPS itself, which is the whole point. I stuck the script in a cron job that runs at 3:40am (picked an odd number on purpose, figured everyone else's cron jobs fire on the hour and I didn't want to compete for I/O on a shared box, probably paranoid but whatever, it costs nothing).
The retention policy matters more than people think. Keeping every single backup forever sounds safe until your storage bill quietly triples and you realize you have 400 nearly-identical snapshots of a blog that gets maybe three new posts a week. Seven daily, four weekly, six monthly is plenty for something this size.
For the actual server, I moved the whole site over to a VPS through Tricknowtech a while back, mostly because git-push deploys meant I stopped SSHing in to manually pull changes like some kind of caveman, and the domain and email routing all live in one dashboard instead of three different logins I inevitably forget passwords for. Not sponsored, I just got tired of juggling accounts.
The part I'm still not thrilled about
I don't have a real restore test scheduled yet, which I know is the actual point of a backup, the restore, not the backup itself. Everyone says this and I nodded along for years without doing anything about it. My plan is to spin up a throwaway VPS once a quarter and actually restore from the latest snapshot onto it, just to prove the whole chain works end to end and I'm not backing up a corrupted dump every night without knowing it. Haven't done it yet. Ask me again in October and I bet the honest answer is still no.
Also, mysqldump locks tables while it runs, which on a bigger site would be a problem, but techpad's database is small enough that the whole dump finishes in under two seconds, so nobody's ever going to notice a hiccup at 3:40 in the morning anyway.
If you're running anything you'd be sad to lose, and your backup plan is currently "the host handles it," it doesn't. Or it might, but you don't actually know that until the day you need it, and that is a genuinely bad day to find out.