【自宅サーバー二重防壁】Restic + Cloudflare R2 + 宅内NASで組む「3-2-1」WordPress自動バックアップ環境

この記事は約11分で読めます。
この記事が役立ったらブックマーク! あとで読み返したり、環境構築時のリファレンスに活用できます
B! はてなブックマークに追加

個人ブログや技術サイトを自宅サーバーで運用する際、最も怖いのが「ストレージ障害」「停電」「ランサムウェア」などの致命的なデータ損失です。
バックアップの鉄則に「3-2-1ルール」(3つのコピー、2つの異なるメディア、1つのオフサイト保管)がありますが、これを個人・自宅サーバー環境でコストをかけずに実現するのは意外と骨が折れます。

今回は、オープンソースのバックアップツール Restic を軸に、「宅内NAS(ローカル)」+「Cloudflare R2(格安クラウド)」 の二重体制をシェルスクリプト1本で自動化する構成を紹介します。

1. システム構成の全体像

  • Webサーバー: Ubuntu(WordPress 複数サイト稼働、RAMディスク併用)
  • リポジトリ①(オンサイト): 宅内NAS(TeraStation / CIFSマウント)
    • メリット: 同一LAN内のためリストア・転送が爆速
  • リポジトリ②(オフサイト): Cloudflare R2(S3互換オブジェクトストレージ)
    • メリット: 自宅が被災・停電してもデータが残る、下り転送(Egress)料金が完全無料
  • エンジン: Restic
    • 暗号化、重複排除(Deduplication)、増分バックアップを標準搭載

2. なぜRestic × Cloudflare R2なのか?

一般的な tar + rsync や WordPressプラグイン(UpdraftPlus等)に比べ、この構成には圧倒的な強みがあります。

  1. 暗号化が標準: クラウド(R2)にデータを預ける際も、クライアント側(サーバー側)でAES-256暗号化されてから送信されるため、盗聴や漏洩のリスクが極めて低い。
  2. 重複排除(Deduplication)の恩恵: サイト全体のファイル群(数GB)を毎日バックアップしても、差分ブロックしか送信・保存されません。追加の通信量・保存容量は数MB〜数十MBに抑えられます。
  3. コストがほぼゼロ: Cloudflare R2はストレージ料金が格安(10GBまで無料枠あり)で、他のクラウド(AWS S3等)と違って「復元時に発生する下り転送量(Egress)」が一切かかりません。

3. 自動バックアップスクリプトの実装

複数サイト(本館・別館など)のDBダンプ、RAMディスクの圧縮退避、2箇所への同時転送、古い世代の自動ローテーション(7日分保持)を1つのシェルスクリプトで完結させています。

スクリプト本体(/root/scripts/wp-backup.sh)

Bash
#!/bin/bash

# ==========================================
# ⚙️ 共通設定(認証情報・リポジトリ)
# ==========================================
RESTIC_PASSWORD="YOUR_SECURE_PASSWORD"
export AWS_ACCESS_KEY_ID="YOUR_R2_ACCESS_KEY_ID"
export AWS_SECRET_ACCESS_KEY="YOUR_R2_SECRET_ACCESS_KEY"
export RESTIC_PASSWORD

# リポジトリの場所
NAS_REPO="/mnt/nas_backup"
R2_REPO="s3:https://<ACCOUNT_ID>.r2.cloudflarestorage.com/<BUCKET_NAME>"

# 一時作業ディレクトリ
TMP_BACKUP_DIR="/tmp/wp_backup_files"

# ==========================================
# 📂 サイトごとの個別設定
# 形式:「識別名 ディレクトリパス DB名 DBユーザー DBパス」
# ==========================================
SITES=(
    "main_site /var/www/example.com main_db_name main_db_user main_db_pass"
    "tech_site /var/www/sub.example.com sub_db_name sub_db_user sub_db_pass"
)

RAM_DISK_DIR="/mnt/ramdisk"

echo "=== [$(date '+%Y-%m-%d %H:%M:%S')] バックアップ処理開始 ==="

for SITE_INFO in "${SITES[@]}"; do
    read -r SITE_NAME BACKUP_TARGET_DIR DB_NAME DB_USER DB_PASS <<< "${SITE_INFO}"

    echo "▶️ 【${SITE_NAME}】処理中..."
    rm -rf "${TMP_BACKUP_DIR}" && mkdir -p "${TMP_BACKUP_DIR}"

    # 1. データベースのダンプ
    mysqldump -u"${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" > "${TMP_BACKUP_DIR}/${SITE_NAME}_db.sql"

    # 2. RAMディスクデータのアーカイブ(利用している場合)
    if [ -d "${RAM_DISK_DIR}" ]; then
        tar -czf "${TMP_BACKUP_DIR}/${SITE_NAME}_ramdisk.tar.gz" -C "${RAM_DISK_DIR}" .
    fi

    # 3. 宅内NASへ送信(リポジトリ①)
    restic -r "${NAS_REPO}" backup "${BACKUP_TARGET_DIR}" "${TMP_BACKUP_DIR}"

    # 4. Cloudflare R2へ送信(リポジトリ②)
    restic -r "${R2_REPO}" backup "${BACKUP_TARGET_DIR}" "${TMP_BACKUP_DIR}"
done

# ==========================================
# 🧹 古いバックアップのお掃除(7日分をキープ)
# ==========================================
echo "🧹 世代ローテーション実行中..."
restic -r "${NAS_REPO}" forget --keep-within 7d --prune
restic -r "${R2_REPO}" forget --keep-within 7d --prune

rm -rf "${TMP_BACKUP_DIR}"
echo "=== [$(date '+%Y-%m-%d %H:%M:%S')] すべてのバックアップが正常に完了しました ==="

4. 自動化(cron)と確認用ショートカット

cronの設定

毎朝午前3時に自動実行されるよう crontab に登録します。

Bash
sudo crontab -e
Plaintext
0 3 * * * /root/scripts/wp-backup.sh >> /var/log/wp-backup.log 2>&1

スナップショット一覧を一発確認するエイリアス

NASとR2の両方のスナップショットをターミナルでサッと見られるよう、/usr/local/bin/restic-list などの確認スクリプトを用意しておくと便利です。

Bash
sudo restic-list
Plaintext
=== 宅内NAS のバックアップ一覧 ===
repository a1b2c3d4 opened (version 2, compression level auto)
ID        Time                 Host           Paths
----------------------------------------------------------------------------------------
1a2b3c4d  2026-09-18 03:00:15  web-server     /tmp/wp_backup_files, /var/www/example.com
5e6f7a8b  2026-09-18 03:00:28  web-server     /tmp/wp_backup_files, /var/www/sub.example.com

=== Cloudflare R2 のバックアップ一覧 ===
(同様に7日分の世代が綺麗に並ぶ)

まとめ:運用してみて分かったこと

  • 帯域への負荷がほぼない: 初回こそ数分かかりますが、2回目以降は変更があった数MBのファイルしか送られないため、数秒〜十数秒で完了します。
  • NAS換装・障害時も安心: どちらか片方のストレージが完全にクラッシュしても、もう一方に暗号化された全世代が生き残っているため、精神的な安心感が段違いです。
  • 運用の手間ゼロ: forget --keep-within 7d --prune により、ディスク容量が溢れる心配もありません。

自宅サーバーでブログを公開している方は、ぜひこの「ローカルNAS + R2」の二重構成を試してみてください。

コメント

タイトルとURLをコピーしました