2 min read

Easy, automated Ghost backups

Easy, automated Ghost backups
Photo by Alex Cheung / Unsplash

The (self-hosted) Ghost blogging platform comes with a handy CLI backup tool ghost backup, but this has a couple of issues - namely that it doesn't run non-interactively, and that it doesn't include a database backup.

Helpfully, a simple guide is provided in the Ghost docs, which was the basis for writing a quick backup script.

I've written a bash script to run this backup process for you and included it as a Gist on Github, but also I've the full script here for convenience:

A couple of notes:

  • Drop the script into your Ghost user home folder (it expects to run as the ghost user - ghost-mgr by default).
  • Backups are saved to ~/ghost-backups/ with a filename like ghost-backup-2026-01-07_18-23-52.zip for easy sorting.
  • To make it really quick and painless, this script automatically pulls the MySQL configuration from your configuration file.
  • This is a bit of a "kitchen sink" approach - it includes the full installation folder, not just the content directory. The files are a bit bigger as a consequence, but personally I'd rather have everything.
  • I'm running a tar of the whole folder and then later zipping it, rather than just doing a tar -z to gzip the file. I realise this is slower, and creates more file I/O, but it has the advantage that the MySQL dump and the content directory get bundled up into a single zip file that's easy to extract and inspect on any system. I always prefer sacrificing a little performance for "self-documenting" solutions.

Here's how it looks when you run it:

ghost@ghost-server:~$ ./ghost-backup.sh /var/www/curiousmentality.net
OK: '/var/www/curiousmentality.net' appears to be a valid Ghost installation.
Running MySQL database backup of curiousmentality_net_prod...
Collecting site folder tarball /var/www/curiousmentality.net...
Compressing everything...
  adding: ghost_db_backup.sql (deflated 87%)
  adding: ghost_content_backup.tar (deflated 70%)
All done, backup file is ghost-backup-2026-01-07_18-23-52.zip

In my case, I then pull the backup files onto my Synology NAS - this keeps them completely separate.

I do that using a scheduled task on the Synology - nice and simple, and that scheduled task is also where I invoke the backup script (over SSH), meaning my Ghost server has a really vanilla config.

The Synology scheduled task looks like this:

ssh -i ~/.ssh/ghost_backup [email protected] "~/ghost-backup.sh /var/www/curiousmentality.net"

rsync -avz -e "ssh -i ~/.ssh/ghost_backup" [email protected]:~/ghost-backups/*.zip /volume1/ghost-backups/

This runs daily, and I get a nice full zip of this Ghost server config dropped on my NAS at 3am 🤓