はじめに

DigitalOcean Droplets(Ubuntu)上で、Docker Composeを用いて複数のGhostブログおよびMySQLデータベースを運用している場合、障害やトラブルへの備えとして、定期的なバックアップおよびクラウドストレージへの保管は非常に重要です。
本記事では、Cloudflare R2をS3互換のバックアップ先として活用し、rcloneを利用して自動でバックアップ・アップロードを行う方法を解説します。

Digital Ocean DropletでDocker ComposeとGhostを使った複数ブログサイトの構築完全ガイド
はじめに:なぜこの構成を選んだのか 現代のWebサイト運営において、複数のブログやサイトを効率的に管理することは多くの開発者やコンテンツクリエイターにとって重要な課題となっています。特に、個人ブログ、技術ブログ、企業サイトなど、異なる目的やターゲット読者を持つサイトを同時に運営する場合、それぞれを独立したサーバーで管理するのはコストと管理の観点から非効率的です。 本記事では、単一のDigital Ocean Droplet上でDocker Composeを活用し、Ghostプラットフォームによる複数ブログサイトを構築する方法を詳しく解説します。この構成により、月額わずか数ドルの小規模サーバーでプロフェッショナルなブログサイトを複数運営できるようになります。また、CaddyをリバースプロキシとしてHTTPS自動化やキャッシュ最適化を実現し、MySQLデータベースで各ブログのデータを分離管理する包括的なソリューションを提供します。 システム概要と技術選択の背景 利用サービスとその選択理由 今回の構成では、以下のサービスとツールを組み合わせて使用します: インフラ

前回のGhost構築の記事はこちらです


1. rcloneのインストール(Ubuntu)

まず、rcloneをインストールしてください。

sudo apt update
sudo apt install rclone

必要に応じて、公式スクリプトによる最新版のインストールもご検討ください。


2. Cloudflare R2リモートの設定

Cloudflare側で「APIトークン(Access Key/Secret Key)」と「Account ID」および「R2バケット名(例: ghost-backups)」を用意してください。

rcloneの設定を行います:

rclone config

主な設定項目は以下の通りです。

  • 名前:r2
  • ストレージタイプ:s3
  • Provider:Cloudflare
  • Access Key ID/Secret Access Key:Cloudflare発行の値
  • Region:auto
  • Endpoint:https://[Cloudflare発行の値].r2.cloudflarestorage.com
  • その他の項目はデフォルトで問題ありません。

3. バックアップスクリプト(Ubuntu対応・rclone版)

以下は、複数GhostインスタンスのコンテンツおよびMySQLデータベースをまとめてバックアップし、Cloudflare R2へアップロードするためのシェルスクリプトです。
(例として /root/git/MyBlogs/ghost_backup_r2.sh などに保存してください。)

#!/bin/bash

set -e

# Base directory for backups
BACKUP_BASE_DIR="/root/ghost_backups"
DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_TMP_DIR="${BACKUP_BASE_DIR}/tmp_${DATE}"
BACKUP_FILE="${BACKUP_BASE_DIR}/ghost_all_${DATE}.tar.gz"

# rclone remote (configured for Cloudflare R2)
RCLONE_REMOTE="r2"
R2_BUCKET_PATH="ghost-backups/ghost_backups"

mkdir -p "$BACKUP_TMP_DIR"

# Copy all Ghost instance content directories automatically
for dir in ./volumes/ghost-*; do
  if [ -d "$dir" ]; then
    cp -r "$dir" "$BACKUP_TMP_DIR/"
  fi
done

# Get MySQL root password from .env file
MYSQL_ROOT_PASSWORD=$(grep '^ROOT_PASSWORD=' .env | cut -d= -f2)

# Get Docker container ID for MySQL
DB_CONTAINER=$(docker-compose ps -q database)

# Export MySQL dump for all databases
docker exec "$DB_CONTAINER" \
  sh -c "mysqldump -uroot -p'\$MYSQL_ROOT_PASSWORD' --all-databases" \
  > "${BACKUP_TMP_DIR}/mysql_all_databases.sql"

# Archive all contents
tar -C "$BACKUP_TMP_DIR" -czf "$BACKUP_FILE" .

# Clean up temporary directory
rm -rf "$BACKUP_TMP_DIR"

echo "Local backup complete: $BACKUP_FILE"

# Upload to Cloudflare R2 via rclone
rclone copy "$BACKUP_FILE" "${RCLONE_REMOTE}:${R2_BUCKET_PATH}/"

echo "Upload to Cloudflare R2 complete"

# Remove local backup files older than 30 days
find "$BACKUP_BASE_DIR" -name "*.tar.gz" -mtime +30 -delete

4. バックアップの自動化(cron設定)

以下のようにcronへ登録することで、定期的な自動バックアップが実現できます。
例:毎日午前3時に実行する場合

crontab -e

以下の行を追加します。

0 3 * * * /root/git/MyBlogs/ghost_backup_r2.sh >> /root/git/MyBlogs/ghost_backup.log 2>&1

注意事項

  • 必要に応じてdocker-composeコマンドのフルパスを記載してください(which docker-composeで確認可能)。
  • .envファイルおよびバックアップディレクトリの権限に注意し、適切なユーザーで運用してください。
  • バックアップファイルの保存先や保持期間は、ご利用方針に合わせて調整してください。
  • Cloudflare R2バケット側でもライフサイクル設定等を活用し、ストレージ運用方針に沿った管理を推奨いたします。

この運用により、Ghostブログの追加・増設にも対応しつつ、堅牢な自動バックアップ体制を構築することが可能です。

Cloudflare R2 Object Storage用Account API Tokenの発行手順
CloudflareのR2でAPIを利用できるようにするためには、事前にAPIに対する設定が必要です。Cloudflareにログインして、R2 Object StorageのOverviewを選択します。 OverviewのAPIプルダウンのManage API tokensを選択します。 Create Account API tokenボタンをクリックします。 以下のように、入力してCreate Account API tokenボタンをクリックします。 * Token Name : 任意の名前 * Permissions : Admin Object Read & Writeor Object Read & Write * Specify buckets : 利用するバケットを入力 * TTL : Forever (一時利用であれば期限を設けた方が良い) * Client IP Address Filtering : 利用するサーバがIP固定であれば設定した方が良い 発行されたTokenは、一度しか表示されないため、控えておいてください。このTokenが知られる