2026年7月6日

2026年7月6日

バックアップのスケジューリングと自動化のベストプラクティス(cron・systemdタイマー・WP-Cron)

バックアップの自動化で大事なのは、決まった時刻に動かすことよりも、「動かなかったときに気づける」「重なって動かない」「サイトに負荷をかけない」の3点です。この記事では、取得頻度と時刻の決め方、WP-Cron に任せる場合の注意点、サーバーの cron や systemd タイマーで動かす設定例、失敗を検知する仕組みまでを、WordPressサイトを例に説明します。

頻度は「失ってよいデータの量」から決める

最初に決めるのは、何時間分のデータまでなら失ってもよいかです。毎日1回のバックアップなら、最悪で約24時間分の投稿・コメント・注文・会員登録が失われます。

WordPressでは、更新の頻度がデータの種類によって大きく違います。

  • データベース:投稿、設定、コメント、ECの注文などが入り、日々変わります。ECや会員サイトなら1日数回、一般的なブログでも1日1回は取りたいところです。
  • アップロードファイル:画像やPDFは追加が中心で、更新頻度は投稿のペース次第です。
  • テーマ・プラグイン:更新したときだけ変わります。

すべてを同じ頻度で取る必要はありません。データベースは短い間隔、ファイルは1日1回や週1回、と分けると、負荷と容量を抑えながら失うデータを減らせます。

時刻の決め方

アクセスの少ない時間帯を選ぶ

バックアップ中はディスクの読み込みとCPUの使用が増え、データベースのダンプも負荷になります。アクセス解析でアクセスが少ない時間帯を確認し、そこに合わせます。国内向けサイトなら深夜から早朝が多いですが、海外からのアクセスやクローラーの巡回が多い時間帯もあるので、実際の数字で確認してください。

ちょうどの時刻を避ける

1台のサーバーで複数サイトを運用している場合、すべてを「3時00分」に設定すると同時に動いて負荷が集中します。サイトごとに15分程度ずらす、ほかの定期処理(ログのローテーション、更新の確認など)とも重ならない時刻にする、といった配慮が有効です。外部のストレージも、利用者が多い「ちょうどの時刻」は混みやすい傾向があります。

サーバーのタイムゾーンを確認する

cron はサーバーのタイムゾーンで動きます。VPSでは UTC のままになっていることが多く、「3時」に設定したつもりが日本時間の正午になっていた、ということが起こります。timedatectl で確認してから時刻を決めてください。

WP-Cron に任せる場合の注意点

UpdraftPlus や BackWPup などのバックアップ用プラグインの多くは、スケジュール実行に WP-Cron を使います。WP-Cron は、サイトにアクセスがあったときに、予定時刻を過ぎた処理を実行する仕組みです。そのため次のような弱点があります。

  • アクセスが少ないサイトでは、予定時刻を過ぎても実行されない
  • 深夜に設定しても、実際には朝の最初のアクセスで動き、アクセスの多い時間に負荷がかかる
  • サーバーの PHP 実行時間の上限で、大きなバックアップが途中で止まることがある

対策として、WP-Cron をアクセス契機で動かすのをやめ、サーバーの cron から定期的に起動する方法があります。wp-config.php に次を追加します。

define( 'DISABLE_WP_CRON', true );

そのうえで、サーバーの cron から WP-CLI で予定時刻を過ぎたイベントを実行します。

*/5 * * * * cd /var/www/html && /usr/local/bin/wp cron event run --due-now --quiet

DISABLE_WP_CRON を入れたのに cron 側を設定し忘れると、バックアップだけでなく予約投稿や更新の確認も止まります。追加したら wp cron event list で、予定時刻が過ぎたまま残っているイベントがないかを確認してください。レンタルサーバーでは、管理画面の cron 設定から同じことができる場合があります。

サーバーの cron で直接動かす

VPSなどでシェルを使えるなら、バックアップ処理そのものをスクリプトにして、cron から動かすのが分かりやすい方法です。

#!/bin/bash
# /usr/local/sbin/wp-backup.sh
set -euo pipefail

STAMP=$(date +%Y%m%d-%H%M)
DEST=/srv/backup/example
mkdir -p "$DEST"

# DB 接続情報はコマンドラインに書かず、権限 600 の設定ファイルから読む
mysqldump --defaults-extra-file=/root/.wp-backup.cnf \
  --single-transaction --quick wordpress \
  | gzip > "$DEST/db-$STAMP.sql.gz"

tar -czf "$DEST/files-$STAMP.tar.gz" -C /var/www/html wp-content wp-config.php

# ここまで成功したときだけ、14日より古いものを削除
find "$DEST" -name '*.gz' -mtime +14 -delete

set -euo pipefail は、途中のコマンドが失敗したらそこで止めるための指定です。pipefail がないと、mysqldump が失敗しても後ろの gzip が成功扱いになり、空に近いファイルが「成功」として残ります。古い世代の削除を最後に置いているのも、バックアップが失敗した日に古い世代だけが消えていく事態を避けるためです。

cron には、重なって動かないよう flock を付けて登録します。

15 3 * * * /usr/bin/flock -n /run/lock/wp-backup.lock /usr/local/sbin/wp-backup.sh >> /var/log/wp-backup.log 2>&1

前回のバックアップが長引いて次の実行時刻に重なると、同じファイルへの書き込みが競合したり、負荷が二重にかかったりします。flock -n は、前回分が動いている間は今回分を起動せずに終了します。

systemd タイマーを使う方法

systemd を使うディストリビューションなら、cron の代わりに systemd タイマーも使えます。実行結果が journalctl に残る、停止中に逃した実行を起動後に行える、といった利点があります。

# /etc/systemd/system/wp-backup.service
[Unit]
Description=WordPress backup

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/wp-backup.sh
Nice=10
IOSchedulingClass=idle
# /etc/systemd/system/wp-backup.timer
[Unit]
Description=Run WordPress backup daily

[Timer]
OnCalendar=*-*-* 03:15:00
RandomizedDelaySec=10min
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now wp-backup.timer
systemctl list-timers wp-backup.timer
journalctl -u wp-backup.service -n 50

Persistent=true は、サーバーが止まっていて実行を逃した場合に、起動後に実行する指定です。RandomizedDelaySec は開始時刻をランダムにずらし、複数のサーバーが同時に動くのを避けます。Nice と IOSchedulingClass=idle は、バックアップの優先度を下げてサイトの応答への影響を減らすためのものです(I/Oの優先度が効くかどうかは、ディスクのスケジューラーなどの環境によります)。OnCalendar の時刻も、タイマーの設定でタイムゾーンを指定しない限りサーバーのタイムゾーンで解釈されます。

失敗に気づく仕組みを作る

自動化したバックアップで最も多い事故は、「いつからか止まっていたのに誰も気づかなかった」というものです。成功・失敗のメールを毎日受け取る方法は、慣れると読まなくなります。

効果的なのは、「成功したら通知する」のではなく「成功の連絡が来なかったら知らせる」仕組みです。スクリプトの最後で、外部の死活監視サービス(Healthchecks.io のようなサービスや、自前の監視ツール)の URL にアクセスし、決まった時間内にアクセスがなければアラートを出すように設定します。

# スクリプトの最後(ここまで到達したときだけ成功を報告)
curl -fsS -m 10 --retry 3 https://monitor.example.com/ping/your-check-id > /dev/null

あわせて、次の点も定期的に確認します。

  • 最新のバックアップファイルの日時とサイズ(極端に小さくなっていないか)
  • 外部ストレージへの転送が成功しているか
  • 保存先の空き容量

バックアップ用プラグインでも、多くは完了・失敗時のメール通知を設定できます。表記や対応する通知先はプラグインやバージョンで違うため、それぞれの設定画面で確認してください(2026年10月現在)。

更新作業の前にも取る

定期バックアップとは別に、WordPress本体やプラグインの更新、テーマの変更、PHPのバージョン変更の前には、その場でバックアップを取っておくと戻すのが楽になります。自動更新を有効にしている場合は、更新が動く前に直近のバックアップがある状態にしておくと安心です。

まとめ

  • 頻度はデータの種類ごとに、失ってよい量から決める。データベースは短い間隔に
  • 時刻はアクセスの少ない時間帯を実データで選び、複数サイトや他の定期処理とずらす
  • WP-Cron はアクセス契機で動くため、決まった時刻に動かしたいならサーバーの cron から起動する
  • スクリプトは失敗時に止まるようにし、古い世代の削除は成功後に行う。flock で重複実行を防ぐ
  • 「成功の連絡が来なかったら知らせる」監視で、止まっていることに早く気づく

お気軽にご相談ください

お見積りへ お問い合わせへ
▲