2026年5月20日
2026年5月20日
WordPressのデータベースのバックアップを自動化する方法
はじめに
手動バックアップは忘れがちです。cronとシェルスクリプトを組み合わせることで、毎日決まった時間に自動でデータベースをバックアップし、クラウドに転送できます。更新作業前の手動バックアップと組み合わせることで二重の安全網が構築できます。
症状・原因
- バックアップを取るのを忘れていてデータを失った
- 手動バックアップが不定期になっている
- バックアップはあるが全部ローカルにしか保存していない
- プラグインの自動バックアップが失敗しても気づかない
解決手順
ステップ1:自動バックアップシェルスクリプトを作成する
#!/bin/bash
# /usr/local/bin/wp-db-backup.sh
# 毎日午前2時に自動実行
# === 設定 ===
WP_PATH="/var/www/html"
BACKUP_DIR="/home/user/db_backups"
KEEP_DAYS=7 # バックアップ保持日数
ADMIN_EMAIL="admin@example.com"
# === 初期化 ===
mkdir -p "$BACKUP_DIR"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/wp_db_$DATE.sql.gz"
LOG_FILE="/var/log/wp-db-backup.log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"; }
# === wp-config.php から認証情報を取得 ===
DB_NAME=$(wp --path="$WP_PATH" config get DB_NAME 2>/dev/null)
DB_USER=$(wp --path="$WP_PATH" config get DB_USER 2>/dev/null)
DB_PASS=$(wp --path="$WP_PATH" config get DB_PASSWORD 2>/dev/null)
DB_HOST=$(wp --path="$WP_PATH" config get DB_HOST 2>/dev/null)
# === バックアップ実行 ===
log "Starting DB backup: $BACKUP_FILE"
mysqldump \
-h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" \
--single-transaction --routines --triggers \
"$DB_NAME" | gzip > "$BACKUP_FILE"
if [ $? -eq 0 ]; then
SIZE=$(du -sh "$BACKUP_FILE" | cut -f1)
log "Backup SUCCESS: $BACKUP_FILE ($SIZE)"
chmod 600 "$BACKUP_FILE"
else
log "Backup FAILED"
echo "DBバックアップが失敗しました。確認してください。" | \
mail -s "[WP] DBバックアップ失敗" "$ADMIN_EMAIL"
exit 1
fi
# === 古いバックアップを削除 ===
find "$BACKUP_DIR" -name "wp_db_*.sql.gz" -mtime +$KEEP_DAYS -delete
log "Cleanup: removed backups older than $KEEP_DAYS days"
ステップ2:cron に登録する
# スクリプトに実行権限を付与
chmod +x /usr/local/bin/wp-db-backup.sh
# crontab を編集
crontab -e
# 以下を追加:
# 毎日午前2時にバックアップ
0 2 * * * /usr/local/bin/wp-db-backup.sh
# 週次でフルバックアップ(日曜午前1時)
0 1 * * 0 /usr/local/bin/wp-db-backup.sh
# cron の設定確認
crontab -l
# cron の実行ログを確認
grep "wp-db-backup" /var/log/cron | tail -20
ステップ3:クラウドストレージへ自動転送する
# rclone を使って Google Drive / S3 に転送
# rclone の設定: rclone config → gdrive または s3 を設定
# バックアップスクリプトに追記
# /usr/local/bin/wp-db-backup.sh の末尾に:
# Google Drive に転送
CLOUD_DEST="gdrive:WordPress-Backups/db"
rclone copy "$BACKUP_FILE" "$CLOUD_DEST" \
--log-level INFO >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
log "Cloud upload SUCCESS: $CLOUD_DEST"
else
log "Cloud upload FAILED"
echo "クラウドへのアップロードが失敗しました。" | \
mail -s "[WP] クラウドバックアップ失敗" "$ADMIN_EMAIL"
fi
# クラウド上の古いバックアップを削除(30日以上)
rclone delete "$CLOUD_DEST" \
--min-age 30d >> "$LOG_FILE" 2>&1
# AWS S3 の場合
# aws s3 cp "$BACKUP_FILE" "s3://my-wp-backups/db/"
ステップ4:WordPressのWP-Cronで自動バックアップする
// functions.php: WP-Cron を使った自動バックアップ
// ※ サーバーcronが使えない場合の代替手段
add_action('daily_db_backup', 'run_daily_db_backup');
function run_daily_db_backup(): void {
global $wpdb;
$backup_dir = WP_CONTENT_DIR . '/backups';
if (!is_dir($backup_dir)) {
wp_mkdir_p($backup_dir);
// .htaccess でウェブアクセスを禁止
file_put_contents($backup_dir . '/.htaccess', 'Require all denied');
}
$filename = $backup_dir . '/db_' . date('Ymd_His') . '.sql';
// テーブル一覧を取得してSQLを生成
$tables = $wpdb->get_col('SHOW TABLES');
$sql = '';
foreach ($tables as $table) {
$create = $wpdb->get_row("SHOW CREATE TABLE `$table`", ARRAY_N);
$sql .= $create[1] . ";\n\n";
$rows = $wpdb->get_results("SELECT * FROM `$table`", ARRAY_A);
foreach ($rows as $row) {
$values = array_map(fn($v) => $v === null ? 'NULL' : "'" . esc_sql($v) . "'", $row);
$sql .= "INSERT INTO `$table` VALUES (" . implode(',', $values) . ");\n";
}
$sql .= "\n";
}
file_put_contents($filename, $sql);
// 古いバックアップを削除(7日以上)
foreach (glob($backup_dir . '/db_*.sql') as $file) {
if (filemtime($file) < strtotime('-7 days')) {
unlink($file);
}
}
}
if (!wp_next_scheduled('daily_db_backup')) {
wp_schedule_event(strtotime('tomorrow 02:00:00'), 'daily', 'daily_db_backup');
}
ステップ5:バックアップの成否を監視する
# バックアップ監視スクリプト(毎朝9時に確認)
#!/bin/bash
# 前日のバックアップが存在するか確認
BACKUP_DIR="/home/user/db_backups"
YESTERDAY=$(date -d "yesterday" +%Y%m%d)
ADMIN_EMAIL="admin@example.com"
# 前日の日付を含むバックアップファイルを検索
BACKUP_FILE=$(find "$BACKUP_DIR" -name "wp_db_${YESTERDAY}*.sql.gz" | head -1)
if [ -z "$BACKUP_FILE" ]; then
echo "警告: ${YESTERDAY}のDBバックアップが見つかりません。
バックアップスクリプトが正常に実行されているか確認してください。
ログ確認: tail -50 /var/log/wp-db-backup.log" | \
mail -s "[WP] バックアップ未検出" "$ADMIN_EMAIL"
else
SIZE=$(du -sh "$BACKUP_FILE" | cut -f1)
echo "バックアップ確認OK: $BACKUP_FILE ($SIZE)"
fi
注意事項
- WP-Cronはサイトへのアクセスがないと実行されません。アクセスの少ないサイトでは
wp-cron.phpをDISABLE_WP_CRONで無効化し、サーバーのcronで直接呼び出すことを推奨します - バックアップファイルはウェブ公開ディレクトリに保存しないでください。
WP_CONTENT_DIR/backups/に保存する場合は必ず.htaccessでアクセスを禁止してください - クラウドへの転送には追加の通信費用が発生する場合があります
まとめ
自動DBバックアップは①wp config getで認証情報を取得するmysqldumpスクリプトを作成、②crontab -eで毎日午前2時に自動実行・失敗時はメール通知、③rcloneでGoogle Drive/S3に自動転送・30日超のクラウドファイルを自動削除、④wp_schedule_eventでWP-Cronによる7日ローテーション付きPHPバックアップ、⑤翌朝9時に前日バックアップの存在確認スクリプトで監視する多層構成を構築します。