テーマをCocoonに変更しました!
wordpress

ConoHa VPSのWordPressを無料で毎日自動バックアップする方法【KUSANAGI】

FavoriteLoadingお気に入り登録
wordpress

こんにちは、優香です。

今回は、ConoHa VPS(KUSANAGI)で動かしているWordPressを、無料で毎日自動バックアップする仕組みを作ったので、その手順を超詳しくまとめておきます。

これまで私はphpMyAdminからデータベースをエクスポートしてバックアップしていたんですが、DBが700MBくらいあるサイトだと途中でエラーになって泣いたことが何度もありました。今回の方法なら、DBのサイズに関係なくサーバーの中で直接バックアップが取れるので、あの苦労はもう不要です。

コマンドをコピペしていくだけで完成するように書いたので、同じようにConoHa VPSやKUSANAGIでWordPressを運用している方は参考にしてみてください。

今回の環境

項目内容
サーバーConoHa VPS(メモリ1GBプラン)
OSAlmaLinux 9
環境KUSANAGI 9
データベースMariaDB
WordPress4サイト(KUSANAGIのプロファイルごとに1サイト)
作業するPCWindows(PowerShellからSSH接続、ファイル確認はWinSCP)

そもそもバックアップの方法は何があるの?

ConoHa VPSでWordPressをバックアップする方法は、大きく分けて3つあります。

方法料金メリットデメリット
ConoHa公式の自動バックアップ有料オプション申し込むだけで毎日自動。サーバー丸ごと復元できるお金がかかる。サイト単位の細かい復元には向かない
WordPressプラグイン(UpdraftPlusなど)無料〜管理画面から設定できて簡単サイトごとに設定が必要。アクセスが少ないと実行が遅れることも
シェルスクリプト+cron無料全サイトまとめて管理できる。DBが大きくてもエラーにならない最初の設定にコマンド操作が必要

最初はConoHa公式の自動バックアップを考えたんですが、有料オプションだったので今回は見送りました(笑)。

ということで今回は、無料でできる「シェルスクリプト+cron」の方法でいきます。

シェルスクリプト+cronってどういう仕組み?

難しそうに聞こえますが、やっていることはシンプルで、「毎晩、VPSが自分でバックアップを取ってくれる仕組み」を作るだけです。

用語意味
シェルスクリプトサーバーにやってほしい作業を1つのファイルにまとめた「作業手順書」
cron(クーロン)「毎日○時にこれを実行して」とサーバーに予約できるタイマー機能

今回作る仕組みの流れはこんな感じです。

  1. 毎日深夜3時になるとcronがスクリプトを起動
  2. 各サイトのデータベースを書き出して圧縮
  3. 各サイトのファイル一式を圧縮
  4. 7日より古いバックアップを自動で削除
  5. 結果をログファイルに記録

寝ている間に勝手にバックアップが取られて、1週間分たまったら古い順に入れ替わっていきます。

WordPressのバックアップは「DB」と「ファイル」の2つが必要

ここ、意外と知らない方も多いと思うので先に説明しておきます。

WordPressのサイトは、実は2つのパーツでできています。

パーツ中身保存場所
データベース(DB)記事の本文、固定ページ、設定、コメントなどMariaDBが管理(DocumentRootの中には無い)
ファイルテーマ、プラグイン、アップロードした画像などDocumentRootの中

この2つは別々の場所で管理されているので、両方バックアップしないと完全には復元できません。

  • ファイルだけ戻す → 見た目は戻るけど、記事が空っぽ
  • DBだけ戻す → 記事はあるけど、画像やテーマが無い

なので今回のスクリプトでは、DBとファイルを別々のファイルとして、同じ日付でセットで保存するようにしています。

ConoHaの管理画面にある「イメージ」「スナップショット」とは?

ConoHaのコントロールパネルを見ていると「イメージ」や「スナップショット」というメニューがあって、何これ?と思ったので調べました。

機能内容料金
保存イメージVPS全体(OS・設定・全サイト)を丸ごと手動で保存。そこからサーバーを戻したり、同じ中身のVPSを作ったりできる各リージョン50GBまで無料
スナップショットこちらも丸ごとコピーだが、作成から24時間で自動削除される一時的なもの
自動バックアップ有料オプション。1日1回自動取得、最大30世代まで管理有料

保存イメージは無料で使えますが、サーバーを停止しないと保存できないのと、使われないまま90日たつと削除対象になるので、毎日のバックアップには向きません。「WordPressの大型アップデートの前」など、大きな作業の前の保険として使うのがおすすめです。

毎日のバックアップは今回のスクリプト、大きな作業の前は保存イメージ、という2段構えにしておけば無料でもかなり安心です。

手順1:現状を確認する

まずはSSHでVPSにログインして、バックアップ対象や空き容量を確認します。ここで実行するコマンドはすべて「見るだけ」なので、何かが変わったり消えたりすることはありません。

プロファイル(サイト)の一覧を確認

ls /home/kusanagi/

KUSANAGIでは、サイトごとに「プロファイル」というフォルダが作られます。ここに表示された名前が、バックアップ対象になるサイトです。

ディスクの空き容量を確認

df -h /

「残り(Avail)」の列が空き容量です。バックアップはVPSの中に保存するので、何日分置けるかの目安になります。私の環境では99GB中85GB空いていたので余裕でした。

各サイトのファイル容量を確認

du -sh /home/kusanagi/*/DocumentRoot

サイトごとのファイルの大きさがわかります。私の環境では4サイトで合計約2.9GBでした。

DBを書き出すコマンドがあるか確認

which mysqldump mariadb-dump

/usr/bin/mariadb-dump と表示されればOKです。今回はこのコマンドを使ってDBを書き出します。

手順2:バックアップスクリプトを作成する

いよいよスクリプトを作ります。以下をまるごとコピーして、ターミナルに貼り付けてEnterしてください(最後の chmod の行まで全部です)。

PROFILES の行は、手順1で確認したご自身のプロファイル名に書き換えてください。複数ある場合は半角スペースで区切ります。

mkdir -p /root/scripts
cat > /root/scripts/wp-backup.sh << 'EOF'
#!/bin/bash
# ============================================
# WordPress 自動バックアップ(KUSANAGI用)
# DB と ファイル(DocumentRoot + wp-config.php) を保存
# ============================================
set -uo pipefail

PROFILES="site1 site2 site3 site4"     # 対象プロファイル(自分の環境に合わせて変更)
BASE=/home/kusanagi
DEST=/root/backups                     # 保存先
KEEP_DAYS=7                            # 保存日数
DATE=$(date +%Y-%m-%d)
LOG=$DEST/backup.log

mkdir -p "$DEST"
chmod 700 "$DEST"

log(){ echo "[$(date '+%F %T')] $*" >> "$LOG"; }

# wp-config.php から定数の値を取り出す
get_conf(){
  grep -E "define\(\s*['\"]$1['\"]" "$2" | head -n1 \
  | sed -E "s/.*define\(\s*['\"]$1['\"]\s*,\s*['\"]([^'\"]*)['\"].*/\1/"
}

log "===== バックアップ開始 ====="

for P in $PROFILES; do
  DIR=$BASE/$P
  OUT=$DEST/$P
  mkdir -p "$OUT"

  # wp-config.php の場所(KUSANAGIは DocumentRoot の1つ上)
  if [ -f "$DIR/wp-config.php" ]; then
    WPCONF=$DIR/wp-config.php
    CONF_REL="$P/wp-config.php"
  elif [ -f "$DIR/DocumentRoot/wp-config.php" ]; then
    WPCONF=$DIR/DocumentRoot/wp-config.php
    CONF_REL=""
  else
    log "[$P] wp-config.php が見つからないのでスキップ"
    continue
  fi

  DB_NAME=$(get_conf DB_NAME "$WPCONF")
  DB_USER=$(get_conf DB_USER "$WPCONF")
  DB_PASS=$(get_conf DB_PASSWORD "$WPCONF")
  DB_HOST=$(get_conf DB_HOST "$WPCONF")
  [ -z "$DB_HOST" ] && DB_HOST=localhost

  # --- DB バックアップ(パスワードは一時ファイル経由で安全に渡す)---
  CNF=$(mktemp)
  chmod 600 "$CNF"
  printf "[client]\nuser=%s\npassword=%s\nhost=%s\n" "$DB_USER" "$DB_PASS" "$DB_HOST" > "$CNF"

  if mariadb-dump --defaults-extra-file="$CNF" --single-transaction --quick \
       --default-character-set=utf8mb4 "$DB_NAME" | gzip > "$OUT/${P}_${DATE}_db.sql.gz"; then
    log "[$P] DB OK ($DB_NAME)"
  else
    log "[$P] DB 失敗 ($DB_NAME)"
  fi
  rm -f "$CNF"

  # --- ファイル バックアップ(キャッシュは除外)---
  if tar czf "$OUT/${P}_${DATE}_files.tar.gz" \
       --exclude="$P/DocumentRoot/wp-content/cache" \
       -C "$BASE" "$P/DocumentRoot" $CONF_REL; then
    log "[$P] ファイル OK"
  else
    log "[$P] ファイル 失敗"
  fi

  # --- 古いバックアップを削除 ---
  find "$OUT" -name "${P}_*" -type f -mtime +$((KEEP_DAYS - 1)) -delete
done

log "===== バックアップ終了 ====="
EOF
chmod 700 /root/scripts/wp-backup.sh

スクリプトの中身をざっくり解説

部分やっていること
PROFILESバックアップするサイト(プロファイル名)の一覧
DESTバックアップの保存先。今回は /root/backups
KEEP_DAYS何日分残すか。7なら1週間分
get_confwp-config.php からDB名・ユーザー名・パスワードを自動で読み取る
mariadb-dumpDBを書き出して、gzipで圧縮して保存
tar czfDocumentRootとwp-config.phpをまとめて圧縮して保存(キャッシュは除外)
find ... -delete保存日数を過ぎた古いバックアップを削除
log結果を backup.log に記録

ここがポイント

  • DBのパスワードをスクリプトに直接書かなくていい。wp-config.phpから自動で読み取るので、サイトを追加するときもPROFILESに名前を足すだけです。
  • パスワードは一時ファイル経由で渡して、使い終わったらすぐ削除しています。コマンドの引数に直接書くと、サーバー内の他のプロセスから見えてしまうことがあるためです。
  • KUSANAGIでは wp-config.phpがDocumentRootの1つ上の階層にあるので、DocumentRootだけ圧縮すると取りこぼします。スクリプトではwp-config.phpも一緒に保存するようにしています。
  • --single-transaction を付けているので、サイトを動かしたままでも整合性のとれたDBバックアップが取れます。

手順3:手動でテスト実行する

いきなり自動化する前に、まずは手動で動かしてみます。

/root/scripts/wp-backup.sh

サイトの大きさによりますが、数分かかります。私の環境(4サイト合計約2.9GB)では約3分で終わりました。コーヒーでも飲んで待ちましょう。

手順4:結果を確認する

ログを確認

cat /root/backups/backup.log

こんな感じで、全サイト「DB OK」「ファイル OK」になっていれば成功です。

[2026-09-21 13:42:54] ===== バックアップ開始 =====
[2026-09-21 13:42:54] [site1] DB OK (site1_db)
[2026-09-21 13:43:10] [site1] ファイル OK
[2026-09-21 13:43:13] [site2] DB OK (site2_db)
[2026-09-21 13:43:50] [site2] ファイル OK
[2026-09-21 13:43:51] [site3] DB OK (site3_db)
[2026-09-21 13:45:00] [site3] ファイル OK
[2026-09-21 13:45:02] [site4] DB OK (site4_db)
[2026-09-21 13:45:45] [site4] ファイル OK
[2026-09-21 13:45:45] ===== バックアップ終了 =====

バックアップファイルを確認

ls -lh /root/backups/*/

サイトごとのフォルダに、こんな感じで2つずつファイルができています。

ファイル名中身
サイト名_日付_db.sql.gzデータベース(記事・設定など)
サイト名_日付_files.tar.gzファイル一式(テーマ・プラグイン・画像・wp-config.php)

私の環境では、1日分で合計約1.7GBでした。圧縮が効くので、元のサイズよりだいぶ小さくなります。7日分でも約12GBなので、空き85GBなら全然余裕です。

DBの中身がちゃんと入っているか確認

記事の少ないサイトだとDBのバックアップが数十KBと小さくなるので、「本当に入ってる?」と不安になるかもしれません。そんなときはこれで確認できます。

zcat /root/backups/site1/site1_2026-09-21_db.sql.gz | grep -c "CREATE TABLE"

WordPressの標準テーブルは12個なので、12以上の数字が出ればOKです。プラグインがテーブルを追加していると、もっと多くなります。私の小さいサイトでも16個入っていました。

よく使う確認コマンドの意味

コマンド意味
lsファイルの一覧を表示
-lサイズや日時など詳しい情報も表示
-hサイズを「324M」のように読みやすい単位で表示
/root/backups/*/backupsの中の全フォルダをまとめて表示
tail -n 10ファイルの最後の10行だけ表示(1回分のログがちょうど10行)

手順5:cronに登録して毎日自動化する

テストがうまくいったら、毎日自動で実行されるようにcronに登録します。今回は毎日深夜3時に実行します。

(crontab -l 2>/dev/null | grep -v wp-backup.sh; echo "0 3 * * * /root/scripts/wp-backup.sh") | crontab -

このコマンドは、今あるcronの設定を残したまま、バックアップの行だけを追加します。何度実行しても同じ行が重複しないようにしてあるので安心です。

「0 3 * * *」の意味

位置意味
1番目0分(0分)
2番目3時(3時)
3番目*日(毎日)
4番目*月(毎月)
5番目*曜日(毎曜日)

つまり「毎日3時0分に実行」という意味です。時間を変えたい場合は2番目の数字を変えればOKです。

登録できたか確認

crontab -l
systemctl is-active crond

0 3 * * * /root/scripts/wp-backup.sh が表示されて、active と出れば登録完了です。すでに他のcron(WordPressのwp-cronなど)を設定している場合も、そちらはそのまま残っています。

翌朝の確認

次の日の朝に、ログを確認してみましょう。

tail -n 10 /root/backups/backup.log

深夜3時の日付でOKが並んでいれば、自動バックアップの完成です。

WinSCPでバックアップを確認する

今回のバックアップは「VPSの中のフォルダにファイルを置いているだけ」なので、ConoHaの管理画面にもWordPressの管理画面にも表示されません。

一番かんたんに確認できるのはWinSCPです。rootでログインして /root/backups/ を開くと、サイトごとのフォルダとバックアップファイルが並んでいます。そのままドラッグすれば、PCにダウンロードすることもできます。

毎日のチェックは、WinSCPで覗いて「日付入りのファイルが増えているか」を見るくらいで十分です。

もしものときの復元方法

バックアップは戻せてこそ意味があるので、復元方法もまとめておきます。

※復元は今のデータを上書きします。実行する前に、念のため今の状態もバックアップしておきましょう。

DBの復元

zcat /root/backups/site1/site1_2026-09-21_db.sql.gz | mariadb -u DBユーザー名 -p DB名

パスワードを聞かれるので、wp-config.phpに書いてあるDBのパスワードを入力します。phpMyAdminのインポートと違って、ファイルサイズの制限もタイムアウトもありません。

ファイルの復元

tar xzf /root/backups/site1/site1_2026-09-21_files.tar.gz -C /home/kusanagi
chown -R httpd:www /home/kusanagi/site1/DocumentRoot

展開したあとは、KUSANAGIのWordPressが正しく動くように所有者を httpd:www に戻しておきます。

DBとファイルは、必ず同じ日付のペアで戻してください。日付がずれると、記事と画像が噛み合わなくなることがあります。

phpMyAdminでエラーになっていた理由

最後に、なぜphpMyAdminだとエラーになって、この方法だと大丈夫なのかを整理しておきます。

比較phpMyAdminmariadb-dump(今回の方法)
動く場所ブラウザ経由(PHPで動作)サーバーの中で直接
サイズ制限PHPのアップロード上限・メモリ上限に引っかかる実質なし
時間制限PHPの実行時間上限でタイムアウトしがちなし
大きなDB(700MBなど)エラーになりやすい普通に取れる
自動化できない(毎回手作業)cronで毎日自動

phpMyAdminはPHPで動いているので、PHPのいろいろな上限に引っかかってしまうんですね。サーバーの中で直接コマンドを実行すれば、そういう制限とは無縁です。

注意点

  • バックアップがVPSの中にしか無いので、VPS自体が壊れたり消えたりすると、バックアップも一緒に消えてしまいます。これは次回の課題です。
  • バックアップにはwp-config.php(DBのパスワード入り)も含まれるので、保存先は /root の下にして、root以外は見られないようにしています。
  • サイトを追加したら、スクリプトの PROFILES に名前を追加するのを忘れずに。
  • ディスクの空き容量は、ときどき df -h / で確認しておきましょう。

まとめ

今回作った仕組みをまとめると、こうなります。

項目内容
スクリプト/root/scripts/wp-backup.sh
保存先/root/backups/プロファイル名/
保存するものDB + ファイル一式(DocumentRoot・wp-config.php)
実行タイミング毎日深夜3時(cron)
保存期間7日分(古いものは自動削除)
ログ/root/backups/backup.log
費用0円

コマンド操作と聞くと身構えてしまいますが、実際にやったことは「スクリプトを貼り付けて、テストして、cronに登録する」だけです。これで寝ている間に毎日バックアップが取られるようになりました。

phpMyAdminのエクスポートでエラーになって泣いていた頃を思うと、本当に楽になりました。同じ悩みを持っている方は、ぜひ試してみてください。

次回予告:Googleドライブに自動保存します

今回の仕組みで毎日のバックアップは取れるようになりましたが、注意点にも書いた通り、バックアップがVPSの中にしか無いのが弱点です。

そこで次回は、rcloneというツールを使って、バックアップをGoogleドライブに自動で保存する仕組みを追加します。これができれば、万が一VPSごと壊れても、Googleドライブからサイトを復元できるようになります。

Googleドライブの無料枠(15GB)に収まるように、何日分を置くかの調整方法も含めてまとめる予定です。お楽しみに!

気になる中古パソコン

パソコン

Supported by Rakuten Web Service

コメント

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

当サイトは、Amazon、楽天アソシエイト・他プログラムの参加者です。リンクを通じて商品を購入すると、紹介料を得る場合があります。

⚠ 免責事項

本記事は、筆者が実際に行った作業を記録したものです。サーバーの環境や設定によっては、同じ手順でも結果が異なる場合があります。

作業を行う際は、事前にバックアップを取ったうえで、ご自身の責任で実施してください。本記事の内容を参考にしたことによって生じたトラブルや損害について、当サイトは一切の責任を負いかねますので、あらかじめご了承ください。