> ## Content Index
> Fetch the complete content index at: https://taiwanding.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Automated Ghost CMS Backups: Cron + Rclone to Google Drive (Full Guide)
- URL: https://taiwanding.com/en/ghost-cms-automated-backup-cron-rclone-google-drive/
- Published: 2026-03-01T12:15:41.000Z
- Updated: 2026-07-15T02:50:27.000Z
- Author: Kevin Chen
- Tags: #en

## Introduction

Right after moving Ghost CMS from KVM 4 to KVM 2 in the last post, one question immediately hit me: **what about backups?**

Hostinger's Daily Backup add-on costs an extra $6/month, which works out to $144 over a 24-month plan. Moving house to save money only to turn around and pay for backups is completely backwards, so I decided to write my own script: schedule backups with cron and sync them to Google Drive with rclone. Zero cost (well, there is *some* cloud cost\~\~).

## Backup Strategy

| Item                   | Setting                                        |
| ---------------------- | ---------------------------------------------- |
| Backup frequency       | Every 12 hours                                 |
| Local retention        | 7 days                                         |
| Google Drive retention | 90 days                                        |
| Backup contents        | MySQL database + Ghost content folder + config |
| Size per backup        | About 160MB (DB 15MB + Content 145MB)          |

## Step 1: Create the Backup Directory

```bash
sudo mkdir -p /var/backups/ghost
sudo chown youruser:youruser /var/backups/ghost

```

## Step 2: Write the Backup Script

```bash
cat > ~/ghost-backup.sh << 'EOF'
#!/bin/bash
# Ghost CMS Auto Backup Script
# Local retention 7 days, Google Drive retention 90 days

BACKUP_DIR="/var/backups/ghost"
DATE=$(date +%Y%m%d_%H%M%S)
GHOST_DIR="/var/www/ghost"

echo "[$(date)] Starting Ghost backup..."

# Back up the database
mysqldump --no-tablespaces -u ghost_user -p'你的密碼' ghost_db > "$BACKUP_DIR/ghost-db-$DATE.sql"

# Back up the content folder (themes, images, config file)
sudo tar czf "$BACKUP_DIR/ghost-content-$DATE.tar.gz" -C "$GHOST_DIR" content/ config.production.json

# Delete local backups older than 7 days
find "$BACKUP_DIR" -name "ghost-*" -mtime +7 -delete

echo "[$(date)] Backup complete: $BACKUP_DIR/ghost-db-$DATE.sql + ghost-content-$DATE.tar.gz"

# Upload to Google Drive
rclone copy "$BACKUP_DIR/ghost-db-$DATE.sql" gdrive:ghost-backups/
rclone copy "$BACKUP_DIR/ghost-content-$DATE.tar.gz" gdrive:ghost-backups/

# Delete Google Drive backups older than 90 days
rclone delete gdrive:ghost-backups/ --min-age 90d

echo "[$(date)] Uploaded to Google Drive"
EOF

chmod +x ~/ghost-backup.sh

```

## Step 3: Fix the Content Folder Permission Issue

Ghost's content folder is owned by `ghost:ghost`, so a regular user running tar will hit `Permission denied`. Set up passwordless sudo for tar:

```bash
echo "youruser ALL=(ALL) NOPASSWD: /usr/bin/tar" | sudo tee /etc/sudoers.d/ghost-backup

```

Now the `sudo tar` in the script won't get stuck waiting for a password.

## Step 4: Install and Configure Rclone

### Install Rclone

```bash
sudo apt install -y rclone

```

If apt can't find it, use the official install script:

```bash
curl https://rclone.org/install.sh | sudo bash

```

### Set Up the Google Drive Connection

The VPS has no browser, so you need to authorize in headless mode:

```bash
rclone config

```

Follow the steps in order:

1. `n` (New remote)
2. Enter `gdrive` for the Name
3. Choose `drive` (Google Drive) for Storage
4. client\_id → just press Enter (use the built-in key)
5. client\_secret → just press Enter
6. scope → choose `1` (Full access)
7. service\_account\_file → Enter to skip
8. Edit advanced config → `n`
9. Use auto config → **`n`** (important! On a VPS you must choose No)

At this point a string of authorization commands appears:

```
rclone authorize "drive" "eyJzY29wZSI6ImRyaXZlIn0"

```

### Complete the Authorization on Your Local Machine

Run that command on a computer that has a browser (your Kali box):

```bash
# First install rclone (if you haven't already)
curl https://rclone.org/install.sh | sudo bash

# Run the authorization
rclone authorize "drive" "eyJzY29wZSI6ImRyaXZlIn0"

```

The browser opens the Google login page automatically, and once you authorize, the terminal prints a token string. Copy the whole token and paste it back into the VPS at the `config_token>` prompt.

Finally:

- Configure as Shared Drive → `n`
- Keep this remote → `y`
- `q` to quit

### Test the Connection

```bash
# Create the backup folder on Google Drive
rclone mkdir gdrive:ghost-backups

# Confirm the folder exists
rclone lsd gdrive:

```

## Step 5: Set Up the Cron Schedule

Run the backup automatically every 12 hours, with logs written to `/var/log/ghost-backup.log`:

```bash
(crontab -l 2>/dev/null; echo "0 */12 * * * /home/youruser/ghost-backup.sh >> /var/log/ghost-backup.log 2>&1") | crontab -

```

Confirm the cron entry was added successfully:

```bash
crontab -l
# You should see:
# 0 */12 * * * /home/youruser/ghost-backup.sh >> /var/log/ghost-backup.log 2>&1

```

## Step 6: Full Test Run

```bash
bash ~/ghost-backup.sh

```

Expected output:

```
[Sun Mar  1 11:57:06 UTC 2026] Starting Ghost backup...
[Sun Mar  1 11:57:12 UTC 2026] Backup complete: /var/backups/ghost/ghost-db-20260301_115706.sql + ghost-content-20260301_115706.tar.gz
[Sun Mar  1 11:57:31 UTC 2026] Uploaded to Google Drive

```

Confirm the files are on Google Drive:

```bash
rclone ls gdrive:ghost-backups/
# 151230801 ghost-content-20260301_115706.tar.gz
#  15515331 ghost-db-20260301_115706.sql

```

## Restore Procedure (Just in Case)

If the day ever comes that you actually need to restore, just pull the files back from Google Drive:

```bash
# List available backups
rclone ls gdrive:ghost-backups/

# Download the backup for a specific date
rclone copy gdrive:ghost-backups/ghost-db-20260301_115706.sql /tmp/
rclone copy gdrive:ghost-backups/ghost-content-20260301_115706.tar.gz /tmp/

# Restore the database
mysql -u ghost_user -p ghost_db < /tmp/ghost-db-20260301_115706.sql

# Restore content
cd /var/www/ghost
sudo tar xzf /tmp/ghost-content-20260301_115706.tar.gz

# Fix permissions
sudo chown -R ghost:ghost /var/www/ghost/content

# Restart Ghost
ghost restart

```

## Cost Comparison

| Option                           | Two-year cost            |
| -------------------------------- | ------------------------ |
| Hostinger Daily Backup           | $6/month × 24 = **$144** |
| DIY Cron + Rclone + Google Drive | **$0**                   |

Same result, $144 saved, and the backup frequency (every 12 hours) is even higher than Hostinger's Daily Backup. Google Drive gives you 15GB free, and at 160MB per backup, 90 days of backups comes to about **28.8GB**... uh, which actually exceeds 15GB.

> ⚠️ **Space estimate**: 160MB × 2/day × 90 days = 28.8GB, over Google Drive's free 15GB. In practice, since it backs up every 12 hours and starts deleting old files after 90 days, the steady state settles at around 28.8GB. If you run out of space, you can drop the Google Drive retention to **45 days** (about 14.4GB), or upgrade to Google One 100GB ($1.99/month).

## Conclusion

Rolling your own backups is easier than it sounds; the whole setup took about 10 minutes. The key pieces are:

1. **mysqldump** to back up the database
2. **tar** to package up content and config
3. **rclone** to push it all to Google Drive
4. **cron** to run it on a schedule
5. **find / rclone delete** to clean up old backups automatically

Next time the VPS acts up, I can restore within 15 minutes. Peace of mind.