Skip to content

Instantly share code, notes, and snippets.

@tcreswick
Created January 6, 2026 23:52
Show Gist options
  • Select an option

  • Save tcreswick/dac99ba6b9a1e11002dfc0a8fc7704fb to your computer and use it in GitHub Desktop.

Select an option

Save tcreswick/dac99ba6b9a1e11002dfc0a8fc7704fb to your computer and use it in GitHub Desktop.
Ghost Blog automated backup script for Ubuntu/Debian
#!/bin/bash
# Fail quickly
set -e
# Check that a folder argument was supplied
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <ghost-install-directory>" >&2
exit 1
fi
# Trim the trailing slash if it exists
GHOST_DIR="${1%/}"
# Generate a name for the backup file
BACKUP_FILE=ghost-backup-$(date +"%Y-%m-%d_%H-%M-%S").zip
# Check that the directory exists
if [ ! -d "$GHOST_DIR" ]; then
echo "Error: '$GHOST_DIR' is not a directory or does not exist." >&2
exit 2
fi
# Check for Ghost config file
if [ ! -f "$GHOST_DIR/config.production.json" ]; then
echo "Error: '$GHOST_DIR' does not appear to be a valid Ghost installation." >&2
echo "Missing: config.production.json" >&2
exit 3
fi
echo "OK: '$GHOST_DIR' appears to be a valid Ghost installation."
# Extract Mysql username and password
GHOST_DB_USER=`jq -r '.database.connection.user' $GHOST_DIR/config.production.json`
GHOST_DB_PASS=`jq -r '.database.connection.password' $GHOST_DIR/config.production.json`
GHOST_DB_NAME=`jq -r '.database.connection.database' $GHOST_DIR/config.production.json`
GHOST_DB_HOST=`jq -r '.database.connection.host' $GHOST_DIR/config.production.json`
# Create or update a MySQL option file (to avoid MySQL warnings)
echo -e "
[client]
user=$GHOST_DB_USER
password=$GHOST_DB_PASS
host=$GHOST_DB_HOST
" > ~/.my.cnf
chmod 600 ~/.my.cnf
# Create backup folder if it doesn't already exist
mkdir -p ~/ghost-backups
# Export the database
echo "Running MySQL database backup of $GHOST_DB_NAME..."
mysqldump \
--single-transaction --no-tablespaces \
$GHOST_DB_NAME \
> ~/ghost-backups/ghost_db_backup.sql
echo "Collecting site folder tarball $GHOST_DIR..."
tar -cf ~/ghost-backups/ghost_content_backup.tar \
-C "$(dirname "$GHOST_DIR")" \
"$(basename "$GHOST_DIR")"
echo "Compressing everything..."
cd ~/ghost-backups || exit 1
zip -m $BACKUP_FILE \
ghost_db_backup.sql \
ghost_content_backup.tar
echo "All done, backup file is $BACKUP_FILE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment