2026年9月26日
2026年9月26日
WordPressで3-2-1バックアップルールを実践する方法|別サーバーとS3に分けて保管
3-2-1ルールとは
3-2-1ルールは、バックアップの置き方の目安です。
- 3: データを3つ持つ(本番の元データ+バックアップ2つ)
- 2: 少なくとも2種類の異なる保存先に置く(同じディスクに2つ置かない)
- 1: そのうち1つは、本番とは離れた場所(別の建物・別の事業者・別のリージョンなど)に置く
同じサーバーの中にバックアップを置くだけでは、ディスク故障、サーバーの乗っ取り、契約の停止、データセンターの障害などで、元データとバックアップを同時に失うおそれがあります。保存先を分けるのは、1つの事故で全部を失わないためです。
WordPressに当てはめた構成例
| 番号 | 置き場所 | 内容 | 防げる事故 |
|---|---|---|---|
| 1 | 本番サーバー | 稼働中のデータベースと wp-content など(元データ) |
— |
| 2 | 別のサーバーやNAS | 毎日のバックアップ(数世代) | 本番ディスクの故障、誤削除 |
| 3 | クラウドのオブジェクトストレージ(例: Amazon S3) | 毎日のバックアップ(数十日分) | サーバー事業者側の障害、本番とバックアップサーバーの同時被害 |
バックアップの対象は、データベースのダンプ、wp-content/(アップロード画像・テーマ・プラグイン)、wp-config.php です。WordPress本体は公式配布物から入れ直せます。
レンタルサーバーの自動バックアップは便利ですが、本番と同じ事業者の中にあるため、3-2-1の「1(離れた場所)」には数えないほうが安全です。
手順1: バックアップを作る
データベースの接続情報はオプションファイルに置き、コマンドラインにパスワードを書かないようにします。
# /root/.my.cnf(chmod 600 にする)
[client]
user=wp_backup
password=ここにパスワード
ダンプとファイルのアーカイブを作るスクリプトです。データベースを先に、ファイルを後に取ります。
#!/bin/bash
# /usr/local/bin/wp-backup-321.sh
set -euo pipefail
SITE_DIR="/var/www/wordpress"
DB_NAME="wordpress_db"
LOCAL_DIR="/var/backups/wp"
STAMP="$(date +%Y%m%d_%H%M)"
mkdir -p "$LOCAL_DIR"
umask 077
# データベース(InnoDBなら公開したまま一貫したダンプが取れる)
mysqldump --single-transaction --no-tablespaces --default-character-set=utf8mb4 \
"$DB_NAME" | gzip > "$LOCAL_DIR/db_${STAMP}.sql.gz"
# ファイル(wp-config.php を含むサイト全体)
tar -czf "$LOCAL_DIR/files_${STAMP}.tar.gz" -C "$(dirname "$SITE_DIR")" "$(basename "$SITE_DIR")"
# 手元には7日分だけ残す
find "$LOCAL_DIR" -name '*.gz' -mtime +7 -delete
この段階では、バックアップはまだ本番サーバーの中にあります。次の手順で外へ出します。
手順2: 別のサーバーへ転送する(2つ目の保存先)
SSHの鍵認証を使い、rsync でバックアップ用サーバーへ送ります。鍵はバックアップ専用に作り、送り先ではバックアップ用ディレクトリ以外に書けないユーザーを使います。
ssh-keygen -t ed25519 -f /root/.ssh/wp_backup -N ""
ssh-copy-id -i /root/.ssh/wp_backup.pub backup@backup.example.net
スクリプトの末尾に追記します。
rsync -a -e "ssh -i /root/.ssh/wp_backup" \
"$LOCAL_DIR/db_${STAMP}.sql.gz" "$LOCAL_DIR/files_${STAMP}.tar.gz" \
backup@backup.example.net:/srv/backup/wordpress/
送り先で --delete 付きの同期をすると、本番で消したファイルが送り先からも消えます。ここでは日付つきのファイルを追加していくだけにし、古い世代は送り先側で削除します。日付ごとの世代管理はrsyncでWordPressをバックアップする方法も参考になります。
手順3: Amazon S3へアップロードする(離れた場所)
AWS CLIを入れ、バックアップ専用のIAMユーザー(またはロール)の認証情報を設定します。
S3のバケットでは、あらかじめバージョニングを有効にしておきます。上書きや削除があっても以前の版が残ります。
aws s3api put-bucket-versioning --bucket example-wp-backup \
--versioning-configuration Status=Enabled
本番サーバーに置く認証情報には、アップロード(s3:PutObject)だけを許可します。本番サーバーが乗っ取られても、その認証情報でバックアップを消せないようにするためです。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::example-wp-backup/*"
}
]
}
スクリプトの末尾に追記します。
aws s3 cp "$LOCAL_DIR/db_${STAMP}.sql.gz" "s3://example-wp-backup/wordpress/db/"
aws s3 cp "$LOCAL_DIR/files_${STAMP}.tar.gz" "s3://example-wp-backup/wordpress/files/"
古い世代の削除は、本番サーバーからではなく、S3のライフサイクルルール(一定日数を過ぎたオブジェクトや旧バージョンを削除する設定)で行います。改ざんや削除からさらに守りたい場合は、S3 Object Lockも検討できます。
S3以外の保存先(Google Cloud Storage、Backblaze B2、Dropbox、Google ドライブなど)を使う場合は、多くのサービスに対応した rclone を使うと、同じ形で rclone copy を書けます。
手順4: cronで毎日実行する
sudo chmod 700 /usr/local/bin/wp-backup-321.sh
sudo crontab -e
# 毎日3時30分に実行し、結果をログに残す
30 3 * * * /usr/local/bin/wp-backup-321.sh >> /var/log/wp-backup-321.log 2>&1
crontabの行に date +%Y%m%d のような % を直接書くと、cronはそれを改行として扱います。日付の処理はスクリプトの中に書き、crontabにはスクリプトを呼ぶ行だけを書くと安全です。また echo "..." | crontab - は既存のcrontabを丸ごと置き換えるので使わないでください。
失敗に気づけるよう、結果をSlackに通知する方法はWordPressのバックアップ結果をSlackに通知する方法で紹介しています。
手順5: 3か所から戻せるか確かめる
定期的に、本番以外の2か所からバックアップを取り出し、検証用のデータベースに読み込みます。
aws s3 cp s3://example-wp-backup/wordpress/db/db_20261001_0330.sql.gz /tmp/
mysql -e "CREATE DATABASE wp_restore_test DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
gunzip -c /tmp/db_20261001_0330.sql.gz | mysql wp_restore_test
mysql -e "SELECT COUNT(*) FROM wp_restore_test.wp_posts WHERE post_status='publish'"
mysql -e "DROP DATABASE wp_restore_test"
ファイルのアーカイブも tar -tzf で中身の一覧を表示し、wp-config.php と wp-content/uploads が含まれているかを確認します。
シェルを使えない場合
レンタルサーバーでSSHやcronを使えない場合は、バックアップ用プラグインで外部ストレージへ送る方法があります。たとえばUpdraftPlusは、Dropbox、Google ドライブ、Amazon S3などへの保存に対応しています。この場合も、サーバー内のコピー、外部ストレージのコピー、手元のPCなどへの定期的なダウンロードで、3つ・2種類・1つは離れた場所、という形をつくれます。
まとめ
- 3-2-1は「1つの事故で全部を失わない」ための置き方の目安です。
- WordPressでは、本番+別サーバー+クラウドのオブジェクトストレージ、の組み合わせが作りやすい構成です。
- 本番サーバーの認証情報ではバックアップを消せないようにし、古い世代の削除は保存先側で行います。
- 戻せることを、本番以外の保存先から定期的に確かめます。