2026年10月4日
2026年10月4日
WordPressのバックアップとデプロイを一元管理する手順(Git・WP-CLI・シェルスクリプト)
WordPress のサイト運用では、「コードの更新(デプロイ)」と「データの保護(バックアップ)」を別々の手順で行っていると、デプロイの直前にバックアップを取り忘れたり、どの時点に戻せばよいか分からなくなったりします。
この記事では、自作のテーマとプラグインを Git で管理してタグ単位でデプロイし、デプロイのたびに同じバックアップスクリプトでデータベースを保存して、1つのログに記録する仕組みを作ります。
何をどこで管理するか
WordPress のサイトには性質の違うものが混ざっています。まず置き場所を分けます。
| 対象 | 管理方法 | 理由 |
|---|---|---|
| 自作のテーマ・プラグイン | Git | 変更履歴を残し、タグを付けた版をデプロイする |
| データベース(投稿・設定・会員など) | バックアップ | サイト上で毎日変わるため、Git では扱わない |
wp-content/uploads(メディア) |
バックアップ | 容量が大きく、サイト上で増えていくため |
wp-config.php |
サーバー上だけに置く | DB のパスワードや認証用キーを含むため、Git に入れない |
| WordPress 本体・配布されているプラグイン | WP-CLI や管理画面で更新 | 自分で書いたコードではないため |
開発環境のデータベースを書き出して本番に読み込むと、本番で増えた投稿やコメントが消えます。デプロイで本番に送るのはコードだけにし、データベースは本番のものを守る対象として扱います。
前提
- WordPress サーバーに SSH で入れ、WordPress のファイルの所有者(この記事では
wpuser)として作業できること - GitHub などに自作テーマ・プラグインのリポジトリがあること
- WordPress は
/var/www/htmlにあり、サイトの URL はhttps://example.com/とします。自分の環境に合わせて読み替えてください。
手順1: WP-CLIを入れる
WP-CLI は、公式サイトの案内どおり phar ファイルを入れます。
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
php wp-cli.phar --info
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
# WordPress を操作できるか確かめる
wp core version --path=/var/www/html
手順2: Gitで管理する範囲を決める
WordPress のディレクトリ全体をリポジトリにしつつ、自作のテーマとプラグインだけを追跡するように .gitignore を書きます。my-theme と my-plugin は自分のディレクトリ名に置き換えます。
/*
!/.gitignore
!/wp-content/
/wp-content/*
!/wp-content/themes/
/wp-content/themes/*
!/wp-content/themes/my-theme/
!/wp-content/plugins/
/wp-content/plugins/*
!/wp-content/plugins/my-plugin/
先頭の /* ですべてを除外し、! で始まる行で必要なディレクトリだけを戻しています。これで wp-config.php、uploads、本体のファイル、配布プラグインはリポジトリに入りません。メンテナンスモードのときに作られる .maintenance も除外されます。
手順3: サーバーをリポジトリにつなぐ
サーバーから GitHub のリポジトリを読めるように、読み取り専用の鍵(GitHub の Deploy key)を作ります。
ssh-keygen -t ed25519 -f ~/.ssh/deploy_key -C "deploy@wp-server"
cat ~/.ssh/deploy_key.pub
表示された公開鍵を、GitHub のリポジトリの Settings → Deploy keys に登録します(書き込み権限は付けません)。~/.ssh/config に次を書くと、GitHub への接続でこの鍵が使われます。
Host github.com
IdentityFile ~/.ssh/deploy_key
IdentitiesOnly yes
WordPress のディレクトリをリポジトリにつなぎます。最初の checkout -f はサーバー上の自作テーマ・プラグインをリポジトリの内容で上書きするので、事前にファイルのバックアップを取り、リポジトリの内容がサーバーと同じであることを確かめてから実行してください。
cd /var/www/html
git init
git remote add origin git@github.com:example/my-site.git
git fetch --tags origin
git checkout -f v1.0.0
git status
v1.0.0 は、サーバーの現状と同じ内容にあたるタグです。git status で、変更されたファイルが無いことを確かめます。
手順4: バックアップスクリプトを作る
毎日のバックアップとデプロイ前のバックアップで、同じスクリプトを使います。引数で「何のためのバックアップか」を渡し、ファイル名に残します。
/home/wpuser/bin/wp-backup.sh:
#!/bin/bash
# 使い方: wp-backup.sh daily / wp-backup.sh pre-deploy
set -euo pipefail
WP_PATH=/var/www/html
DEST=/home/wpuser/backups
KEEP_DAYS=14
REASON=${1:-manual}
STAMP=$(date +%Y%m%d-%H%M%S)
DB_FILE="$DEST/db-$STAMP-$REASON.sql.gz"
mkdir -p "$DEST"
wp db export - --path="$WP_PATH" | gzip > "$DB_FILE"
# メディアは毎日のバックアップのときだけ保存する
if [ "$REASON" = "daily" ]; then
tar -czf "$DEST/uploads-$STAMP.tar.gz" -C "$WP_PATH/wp-content" uploads
fi
find "$DEST" -maxdepth 1 -type f -name '*.gz' -mtime +"$KEEP_DAYS" -delete
# 作ったファイルのパスを出力する(デプロイスクリプトが記録に使う)
echo "$DB_FILE"
wp db export - は、データベースの内容を標準出力に書き出します。ここでは gzip で圧縮して保存しています。
毎日のバックアップを cron に登録します(crontab -e)。
15 3 * * * /home/wpuser/bin/wp-backup.sh daily >> /home/wpuser/backup.log 2>&1
バックアップは同じサーバーの中に置くだけでは、サーバーが壊れたときに一緒に失われます。/home/wpuser/backups を別の場所(クラウドストレージや別のサーバー)にも複製してください。
手順5: デプロイスクリプトを作る
デプロイするタグを受け取り、次の順で処理します。
- タグがあるか、サーバー上で直接変更されたファイルが無いかを確かめる
- 手順4のスクリプトでデータベースをバックアップする
- メンテナンスモードにしてコードを切り替え、キャッシュを消す
- メンテナンスモードを解除し、トップページが表示されるかを確かめる
- 切り替え前後のコミットとバックアップのファイル名をログに残す
/home/wpuser/bin/wp-deploy.sh:
#!/bin/bash
# 使い方: wp-deploy.sh v1.4.0
set -euo pipefail
WP_PATH=/var/www/html
SITE_URL=https://example.com/
LOG=/home/wpuser/deploy.log
TAG=${1:?usage: wp-deploy.sh TAG}
cd "$WP_PATH"
git fetch --tags --quiet origin
if ! git rev-parse --verify --quiet "refs/tags/$TAG" > /dev/null; then
echo "tag $TAG not found" >&2
exit 1
fi
# サーバー上で直接書き換えられたファイルがあれば止める
if [ -n "$(git status --porcelain)" ]; then
echo "local changes found on the server:" >&2
git status --short >&2
exit 1
fi
FROM=$(git rev-parse --short HEAD)
BACKUP=$(/home/wpuser/bin/wp-backup.sh pre-deploy)
# 途中で失敗してもメンテナンスモードが残らないようにする
trap 'wp maintenance-mode is-active --path="$WP_PATH" && wp maintenance-mode deactivate --path="$WP_PATH"' EXIT
wp maintenance-mode activate --path="$WP_PATH"
git -c advice.detachedHead=false checkout --quiet "$TAG"
wp cache flush --path="$WP_PATH"
wp maintenance-mode deactivate --path="$WP_PATH"
if ! curl -fsS -o /dev/null "$SITE_URL"; then
echo "warning: $SITE_URL did not return a success status" >&2
fi
echo "$(date '+%F %T') deploy $FROM -> $TAG backup=$BACKUP" >> "$LOG"
echo "deployed $TAG"
chmod 700 /home/wpuser/bin/wp-backup.sh /home/wpuser/bin/wp-deploy.sh
wp maintenance-mode は WP-CLI に含まれるコマンドで、activate の間は訪問者にメンテナンス中の表示を返します。is-active はメンテナンス中なら終了コード 0 を返すので、trap で終了時に残っていれば解除しています。
手順6: デプロイを実行する
開発側でタグを付けて push します。
git tag v1.4.0
git push origin v1.4.0
手元の PC から SSH でデプロイスクリプトを呼び出します。サーバーに入らずに、どこからでも同じ手順でデプロイできます。
ssh wpuser@example.com /home/wpuser/bin/wp-deploy.sh v1.4.0
deploy.log には、次のような行が残ります。
2026-11-10 14:05:12 deploy 3f2a9c1 -> v1.4.0 backup=/home/wpuser/backups/db-20261110-140510-pre-deploy.sql.gz
手順7: 問題があったときに戻す
コードだけを戻す場合は、deploy.log の矢印の左側(切り替え前のコミット)をチェックアウトします。
cd /var/www/html
git -c advice.detachedHead=false checkout --quiet 3f2a9c1
wp cache flush --path=/var/www/html
デプロイしたコードがデータベースを書き換えて壊した場合は、ログに記録されたデプロイ前のバックアップを読み込みます。
gunzip -c /home/wpuser/backups/db-20261110-140510-pre-deploy.sql.gz | wp db import - --path=/var/www/html
データベースを戻すと、バックアップを取った後に増えた投稿・コメント・注文などは失われます。コードを戻すだけで直る場合は、データベースは戻さないでください。
運用の注意
- サーバー上でファイルを直接編集しない: テーマファイルエディターや FTP で直接書き換えると、次のデプロイで止まります(手順5の確認)。変更はリポジトリを通して行います。
- 管理画面のファイル編集を止める:
wp-config.phpにdefine( 'DISALLOW_FILE_EDIT', true );を書くと、管理画面のテーマファイルエディターとプラグインファイルエディターが使えなくなります。 - 復元を練習する: バックアップから別の環境に戻せるかを、定期的に確かめます。
- 鍵の権限を絞る: サーバーに置くのは読み取り専用の Deploy key だけにし、書き込みできる鍵は置きません。
まとめ
- コードは Git、データベースとメディアはバックアップと、管理の仕方を分ける
.gitignoreで自作のテーマ・プラグインだけを追跡し、wp-config.phpやuploadsは入れない- デプロイの前にはバックアップスクリプトでデータベースを保存し、切り替え前のコミットとバックアップのファイル名をログに残す
- 戻すときはまずコードだけを戻し、データベースの復元は失われるデータを確かめてから行う
関連記事: