<p>本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">wp-cliでWordPressサイトをコマンドライン管理</h1>
<h2 class="wp-block-heading">1. 要件と前提</h2>
<p>WordPressサイトの管理は、GUIベースのダッシュボードを通じて行うのが一般的ですが、DevOpsの文脈では、構築、更新、バックアップ、デプロイなどの繰り返し作業を自動化し、安定性と効率性を高めることが求められます。<code>wp-cli</code>は、WordPressをコマンドラインから管理するための強力なツールであり、これらの自動化要件を満たす鍵となります。</p>
<h3 class="wp-block-heading">1.1 要件</h3>
<ul class="wp-block-list">
<li><p><code>wp-cli</code>を活用したWordPressサイトのコマンドライン管理手法を理解する。</p></li>
<li><p>自動化スクリプトは<strong>冪等(idempotent)</strong>であること。</p></li>
<li><p>安全な<code>bash</code>スクリプトの記述方法(<code>set -euo pipefail</code>, <code>trap</code>, 一時ディレクトリの利用)を習得する。</p></li>
<li><p>JSONデータ処理に<code>jq</code>を、外部API連携に<code>curl</code>を安全に利用する。</p></li>
<li><p><code>systemd unit</code>と<code>systemd timer</code>を用いて定期的な自動実行を設定する。</p></li>
<li><p>root権限の扱いと権限分離に関するセキュリティ上の注意点を理解する。</p></li>
</ul>
<h3 class="wp-block-heading">1.2 前提環境</h3>
<ul class="wp-block-list">
<li><p>Linux OS (例: Ubuntu, CentOS)</p></li>
<li><p>PHP (WordPressの要件に準拠、CLI版も必要)</p></li>
<li><p>MySQL/MariaDBまたは互換性のあるデータベース</p></li>
<li><p>NginxまたはApacheなどのWebサーバー</p></li>
<li><p><code>wp-cli</code>がインストールされていること</p></li>
<li><p><code>jq</code>, <code>curl</code>がインストールされていること</p></li>
</ul>
<h2 class="wp-block-heading">2. 実装</h2>
<h3 class="wp-block-heading">2.1 wp-cliのインストール</h3>
<p><code>wp-cli</code>は、<code>bash</code>スクリプトを通じてインストールするのが推奨されています。これにより、常に最新の安定版を導入できます。</p>
<div class="codehilite">
<pre data-enlighter-language="generic">#!/bin/bash
# wp-cliインストールスクリプト
set -euo pipefail
WP_CLI_BIN_PATH="/usr/local/bin/wp" # wp-cli実行ファイルのパス
# wp-cliが既に存在するか確認し、存在しなければダウンロード・配置
if ! command -v wp &>/dev/null; then
echo "wp-cliをダウンロードしています..."
curl -o /tmp/wp-cli.phar https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
if [[ ! -f /tmp/wp-cli.phar ]]; then
echo "エラー: wp-cli.pharのダウンロードに失敗しました。" >&2
exit 1
fi
chmod +x /tmp/wp-cli.phar
sudo mv /tmp/wp-cli.phar "$WP_CLI_BIN_PATH"
echo "wp-cliが $WP_CLI_BIN_PATH にインストールされました。"
else
echo "wp-cliは既にインストールされています。"
fi
# シェルのPATHにwp-cliのパスが含まれているか確認
if ! echo "$PATH" | grep -q "$(dirname "$WP_CLI_BIN_PATH")"; then
echo "警告: wp-cliのパス ($(dirname "$WP_CLI_BIN_PATH")) がPATHに含まれていません。"
echo "手動で追加するか、フルパスで実行してください。"
fi
# インストール確認
wp --info
</pre>
</div>
<p>参照: WP-CLI公式ドキュメント – Installing WP-CLI [^1] (最終確認日: 2024年7月26日 JST)</p>
<h3 class="wp-block-heading">2.2 安全なBashスクリプトの記述</h3>
<p>自動化スクリプトは、予期せぬエラーで停止したり、不完全な状態で終了したりしないように、堅牢に記述する必要があります。</p>
<ul class="wp-block-list">
<li><p><code>set -euo pipefail</code>:</p>
<ul>
<li><p><code>set -e</code>: コマンドが失敗した場合、即座にスクリプトを終了します。</p></li>
<li><p><code>set -u</code>: 未定義の変数を使用しようとした場合、エラーを出してスクリプトを終了します。</p></li>
<li><p><code>set -o pipefail</code>: パイプライン中の任意のコマンドが失敗した場合、パイプライン全体が失敗し、スクリプトが終了します。</p></li>
</ul></li>
<li><p><code>trap</code>: スクリプト終了時(成功/失敗問わず)に特定のコマンドを実行します。一時ファイルのクリーンアップなどに役立ちます。</p></li>
<li><p>一時ディレクトリの利用: <code>mktemp -d</code>で作成した一時ディレクトリで作業し、<code>trap</code>で確実に削除することで、ディスク上に不要なファイルが残るのを防ぎます。</p></li>
</ul>
<p>以下の例は、WordPressのデータベースをバックアップし、不要なリビジョンをクリーンアップするスクリプトです。</p>
<div class="codehilite">
<pre data-enlighter-language="generic">#!/bin/bash
# WordPressデータベースバックアップ&最適化スクリプト
set -euo pipefail
# --- 変数定義 ---
WP_PATH="/var/www/html/wordpress" # WordPressのルートディレクトリ
BACKUP_DIR="/var/backups/wordpress_db"
DB_USER="wp_user"
DB_PASS="your_db_password" # 環境変数やシークレット管理ツールで扱うのがより安全
# --- 一時ディレクトリの設定とクリーンアップ ---
# mktemp -dは一時ディレクトリを作成し、そのパスを出力する
TMP_DIR=$(mktemp -d -t wp-db-XXXXXXXX)
# trapでスクリプト終了時に一時ディレクトリを削除
trap 'echo "一時ディレクトリ ${TMP_DIR} を削除しています..."; rm -rf "${TMP_DIR}"' EXIT
# --- 作業ディレクトリへの移動と権限確認 ---
if [[ ! -d "$WP_PATH" ]]; then
echo "エラー: WordPressディレクトリ $WP_PATH が見つかりません。" >&2
exit 1
fi
cd "$WP_PATH" || { echo "エラー: WordPressディレクトリに移動できませんでした。" >&2; exit 1; }
# WordPressのファイルオーナーと実行ユーザーが異なる場合、sudo -uで実行
# 例: Webサーバーユーザー (www-data) でwp-cliを実行
# sudo -u www-data wp ...
# または、スクリプト実行ユーザーに適切な権限を付与する。
# ここではスクリプト実行ユーザーがwp-cliを実行できる前提。
# --- バックアップディレクトリの作成 ---
mkdir -p "$BACKUP_DIR"
# --- データベースのバックアップ ---
echo "WordPressデータベースをバックアップしています..."
BACKUP_FILE="${BACKUP_DIR}/wordpress_db_$(date +%Y%m%d_%H%M%S).sql"
# wp db export コマンドは、デフォルトで.sqlファイルを標準出力に出力しない。
# 直接ファイルに書き込むオプションも持つが、一時ファイル経由も安全。
if wp db export "${TMP_DIR}/current_db.sql" --user="$DB_USER" --pass="$DB_PASS" --path="$WP_PATH"; then
mv "${TMP_DIR}/current_db.sql" "$BACKUP_FILE"
echo "データベースバックアップが $BACKUP_FILE に保存されました。"
else
echo "エラー: データベースのバックアップに失敗しました。" >&2
exit 1
fi
# --- データベースの最適化とクリーンアップ ---
echo "WordPressデータベースを最適化し、不要なリビジョンをクリーンアップしています..."
# 投稿リビジョンを最新の3つ以外削除
# dry-runで確認後、--yesで実行
wp post delete $(wp post list --post_type='revision' --format=ids --allow-root | head -n -3) --force --path="$WP_PATH" --yes
# wp post list --post_type='revision' --format=ids --path="$WP_PATH" | xargs -r wp post delete --force --path="$WP_PATH" --yes # こちらの方がより安全
# 上記コマンドはpost_type='revision'の投稿をすべて取得し、そのうち最後の3つを残して削除する。
# 特定のpost_idを削除するのではなく、リビジョンを削除する場合は `wp revisions delete` を使用するほうが正確。
# 例: wp revisions clean --keep=3 --path="$WP_PATH"
# 今回は一般的なクリーンアップとして wp post delete で代替
# もしくは wp option update "blog_public" 0 でサイトを一時的に非公開にするなども検討
# データベースの最適化
if wp db optimize --path="$WP_PATH"; then
echo "データベースの最適化が完了しました。"
else
echo "警告: データベースの最適化中に問題が発生した可能性があります。" >&2
fi
echo "WordPressデータベースの管理スクリプトが正常に完了しました。"
</pre>
</div>
<h3 class="wp-block-heading">2.3 jq を用いたJSON処理と curl の利用</h3>
<p><code>wp-cli</code>の多くのコマンドは<code>--format=json</code>オプションでJSON形式の出力を生成できます。これを<code>jq</code>で処理することで、複雑な情報を抽出したり、他のシステムと連携したりできます。<code>curl</code>は、外部の監視サービスへの通知や、WordPressサイトの可用性チェックなどに利用できます。</p>
<div class="codehilite">
<pre data-enlighter-language="generic">#!/bin/bash
# WordPressプラグインの更新と通知スクリプト
set -euo pipefail
# --- 変数定義 ---
WP_PATH="/var/www/html/wordpress"
WEBHOOK_URL="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX" # 通知先Webhook URL
SITE_URL="https://your-wordpress-site.com"
# --- 作業ディレクトリへの移動 ---
cd "$WP_PATH" || { echo "エラー: WordPressディレクトリに移動できませんでした。" >&2; exit 1; }
# --- プラグインの更新チェックと更新 ---
echo "利用可能なプラグインの更新を確認しています..."
# wp plugin update --all は、更新があるプラグインのみを更新するため冪等
# --dry-run でまず確認することもできる
UPDATE_OUTPUT=$(wp plugin update --all --format=json --allow-root)
# --allow-root はDocker環境などで必要になることがあるが、通常運用では非推奨。
# 特定のユーザー (例: www-data) で実行するべき。 sudo -u www-data wp plugin update ...
UPDATED_PLUGINS=$(echo "$UPDATE_OUTPUT" | jq -r '.[] | select(.update_status == "Success") | .name')
if [[ -z "$UPDATED_PLUGINS" ]]; then
MESSAGE="WordPressのプラグインに利用可能な更新はありませんでした。"
echo "$MESSAGE"
else
MESSAGE="WordPressプラグインが更新されました:\n${UPDATED_PLUGINS}"
echo -e "$MESSAGE"
fi
# --- サイトの健全性チェックと通知 (curl) ---
echo "サイトの可用性をチェックしています..."
# curlのオプション:
# -sS: Silent but show errors
# --retry 5: 5回までリトライ
# --retry-delay 3: リトライ間の待機時間 (秒)
# --retry-connrefused: 接続拒否でもリトライ
# --max-time 10: 最大10秒でタイムアウト
# --fail-early: 最初の失敗ですぐに終了 (リトライと組み合わせると少し挙動が変わる)
# --output /dev/null: 出力を破棄
# --resolve: DNSルックアップをオーバーライドする (テスト環境などで便利)
if curl -sS --retry 5 --retry-delay 3 --retry-connrefused --max-time 10 --output /dev/null "$SITE_URL"; then
STATUS_MESSAGE="WordPressサイト (${SITE_URL}) は正常に動作しています。"
echo "$STATUS_MESSAGE"
else
STATUS_MESSAGE="エラー: WordPressサイト (${SITE_URL}) が利用できません。または応答が遅延しています。"
echo "エラー: $STATUS_MESSAGE" >&2
# Webhook通知にエラーメッセージを追加
MESSAGE="${MESSAGE}\n${STATUS_MESSAGE}"
fi
# --- Slack Webhookへの通知 ---
if [[ -n "$WEBHOOK_URL" ]]; then
echo "Slackに通知を送信しています..."
# jqでJSONペイロードを生成
PAYLOAD=$(jq -n --arg msg "$MESSAGE" '{text: $msg}')
# curlでWebhookにPOST
# -H "Content-Type: application/json": JSON形式で送信
# -X POST: POSTメソッド
# -d @- : 標準入力からデータを読み込む (PAYLOAD変数をechoでパイプ)
if echo "$PAYLOAD" | curl -sS -H "Content-Type: application/json" -X POST -d @- "$WEBHOOK_URL"; then
echo "通知が正常に送信されました。"
else
echo "エラー: Slackへの通知に失敗しました。" >&2
fi
fi
echo "WordPressプラグイン更新と通知スクリプトが完了しました。"
</pre>
</div>
<h3 class="wp-block-heading">2.4 systemd unit/timer の利用</h3>
<p><code>systemd</code>はLinuxシステムでサービスやタスクを管理するための強力なツールです。<code>timer</code>と<code>unit</code>を組み合わせることで、cronのような定期実行タスクをより柔軟かつ詳細に管理できます。</p>
<p>以下の例では、上記で作成したデータベースバックアップスクリプトを毎日午前2時に実行する設定を示します。</p>
<p><strong>フロー図: systemdによるWordPress自動バックアップ</strong></p>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["systemd timer: wp-db-backup.timer"] -->|毎朝2:00にトリガー| B("systemd service: wp-db-backup.service")
B -->|サービス起動| C["Bashスクリプト: wp-db-backup.sh"]
C -->|wp-cliコマンド実行| D("WordPress DBバックアップ")
C -->|wp-cliコマンド実行| E("WordPress DB最適化")
C -->|終了ステータスを返却| B
B -->|ログ出力| F[journalctl]
</pre></div>
<h4 class="wp-block-heading">2.4.1 サービスユニットファイル (<code>/etc/systemd/system/wp-db-backup.service</code>)</h4>
<div class="codehilite">
<pre data-enlighter-language="generic">[Unit]
Description=WordPress Database Backup and Optimization
Documentation=https://your-documentation-link.com
# After=network-online.target はネットワークが必要な場合に指定
# 今回はDBへのアクセスなので不要な場合も
[Service]
Type=oneshot
# ExecStartPreはExecStartの前に実行されるコマンド
# これにより、スクリプト実行前に必要な環境変数を設定したり、ログディレクトリを作成したりできる
# ExecStart=/bin/bash -c "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /path/to/your/wp-db-backup.sh"
# 環境変数を明示的に設定してスクリプトを実行
ExecStart=/bin/bash -c 'WP_PATH="/var/www/html/wordpress" /usr/local/bin/wp-db-backup.sh'
# 環境変数をスクリプト内で定義済みの場合は、単純にスクリプトパスを指定
# ExecStart=/usr/local/bin/wp-db-backup.sh
# User と Group を指定することで、指定されたユーザー権限でスクリプトが実行される
# これにより、root権限での実行を避け、最小権限の原則を適用できる
# 例: Webサーバーを実行しているユーザーを指定 (例: www-data, nginx)
User=www-data
Group=www-data
# WorkingDirectory はスクリプトが実行されるカレントディレクトリを設定
# スクリプト内で cd している場合は不要だが、設定しておくとより明確
WorkingDirectory=/var/www/html/wordpress
# RestartPolicy は、サービスが失敗した場合の再起動ポリシーを定義
# 今回のType=oneshotの場合、OnFailureが適切
Restart=on-failure
RestartSec=5s # 5秒後に再起動を試みる
# StandardOutputとStandardErrorでログの出力先を制御
# syslogに送信 (journalctlで確認可能)
StandardOutput=syslog
StandardError=syslog
# PrivateTmp=true: サービス専用の一時ディレクトリを作成し、終了時に自動削除
PrivateTmp=true
[Install]
WantedBy=multi-user.target
</pre>
</div>
<p><strong>注意</strong>: <code>ExecStart</code> のパスは、スクリプトの実装場所に合わせ、<code>User</code> と <code>Group</code> はWordPressが動作するユーザーに合わせてください。<code>wp-db-backup.sh</code> スクリプトのパスも適切に更新する必要があります(例: <code>/usr/local/bin/wp-db-backup.sh</code> に配置)。</p>
<h4 class="wp-block-heading">2.4.2 タイマーユニットファイル (<code>/etc/systemd/system/wp-db-backup.timer</code>)</h4>
<div class="codehilite">
<pre data-enlighter-language="generic">[Unit]
Description=Run WordPress Database Backup and Optimization daily
[Timer]
# OnCalendarはタイマーを起動する日時を指定
# "daily": 毎日
# "hourly": 毎時
# "*-*-* 02:00:00": 毎日午前2時 (システムが起動していれば)
OnCalendar=*-*-* 02:00:00
# Persistent=true: システム停止中に期限が過ぎた場合、起動後にすぐに実行される
# (OnCalendarで指定された最後の実行時刻を記憶)
Persistent=true
# AccuracySec=1h: 起動時刻の精度を1時間単位にする(リソース節約)
# 厳密な時刻が必要な場合はコメントアウトするか、より短い時間を設定
AccuracySec=1h
[Install]
WantedBy=timers.target
</pre>
</div>
<h4 class="wp-block-heading">2.4.3 systemd設定の適用と起動</h4>
<ol class="wp-block-list">
<li><p><strong>スクリプトの配置</strong>:
<code>wp-db-backup.sh</code> を <code>/usr/local/bin/</code> など適切な場所に配置し、実行権限を付与します。</p>
<div class="codehilite">
<pre data-enlighter-language="generic">sudo cp wp-db-backup.sh /usr/local/bin/wp-db-backup.sh
sudo chmod +x /usr/local/bin/wp-db-backup.sh
</pre>
</div></li>
<li><p><strong>ユニットファイルの配置</strong>:
上記の<code>.service</code>と<code>.timer</code>ファイルを<code>/etc/systemd/system/</code>に配置します。</p></li>
<li><p><strong>systemdのリロード</strong>:
新しいユニットファイルを認識させるためにsystemdをリロードします。</p>
<div class="codehilite">
<pre data-enlighter-language="generic">sudo systemctl daemon-reload
</pre>
</div></li>
<li><p><strong>タイマーの起動と有効化</strong>:</p>
<div class="codehilite">
<pre data-enlighter-language="generic">sudo systemctl enable wp-db-backup.timer # システム起動時にタイマーが有効になるようにする
sudo systemctl start wp-db-backup.timer # 今すぐタイマーを開始する
</pre>
</div></li>
</ol>
<h2 class="wp-block-heading">3. 検証</h2>
<p>設定した<code>systemd</code>タイマーが正しく動作しているか確認します。</p>
<ol class="wp-block-list">
<li><p><strong>タイマーの状態確認</strong>:</p>
<div class="codehilite">
<pre data-enlighter-language="generic">systemctl list-timers | grep wp-db-backup
</pre>
</div>
<p>出力例:</p>
<pre data-enlighter-language="generic">NEXT LEFT LAST PASSED UNIT ACTIVATES
Fri 2024-07-27 02:00:00 JST 13h left Thu 2024-07-26 02:00:00 JST 11h ago wp-db-backup.timer wp-db-backup.service
</pre>
<p><code>NEXT</code>と<code>LAST</code>の時刻を確認し、<code>LEFT</code>が次回実行までの時間を示していることを確認します。</p></li>
<li><p><strong>サービスのテスト実行</strong>:
タイマーの実行を待たずに、手動でサービスを実行して動作を確認できます。</p>
<div class="codehilite">
<pre data-enlighter-language="generic">sudo systemctl start wp-db-backup.service
</pre>
</div></li>
<li><p><strong>ログの確認</strong>:
実行後のログを<code>journalctl</code>で確認します。</p>
<div class="codehilite">
<pre data-enlighter-language="generic">journalctl -u wp-db-backup.service --since "1 day ago"
</pre>
</div>
<p>スクリプトの<code>echo</code>出力がここに記録されます。エラーメッセージがないか、バックアップファイルが正しく作成されているか確認します。</p></li>
<li><p><strong>バックアップファイルの確認</strong>:
<code>BACKUP_DIR</code>に指定したディレクトリ(例: <code>/var/backups/wordpress_db/</code>)にバックアップファイルが作成されていることを確認します。</p></li>
</ol>
<h2 class="wp-block-heading">4. 運用</h2>
<h3 class="wp-block-heading">4.1 権限管理とroot権限の扱い</h3>
<ul class="wp-block-list">
<li><p><strong>最小権限の原則</strong>: <code>wp-cli</code>スクリプトは、WordPressファイルとデータベースにアクセスする権限を持つ最小限のユーザーで実行すべきです。Webサーバーが動作するユーザー(例: <code>www-data</code>, <code>nginx</code>)を指定するのが一般的です。<code>systemd</code>の<code>User=</code>および<code>Group=</code>ディレクティブを活用します。</p></li>
<li><p><strong>root権限の回避</strong>: <code>wp-cli</code>コマンドに<code>--allow-root</code>オプションは<strong>極力使用を避ける</strong>べきです。開発環境や特殊なコンテナ環境以外で本番環境で使うことは推奨されません。</p></li>
<li><p><strong>データベースパスワード</strong>: データベースユーザーのパスワードは、スクリプトに直接記述せず、環境変数、または<code>wp-cli</code>の設定ファイル(<code>wp-cli.yml</code>)、あるいはSecret Managementツール(HashiCorp Vault, AWS Secrets Managerなど)で管理することを強く推奨します。</p></li>
</ul>
<h3 class="wp-block-heading">4.2 ロギングとモニタリング</h3>
<ul class="wp-block-list">
<li><p><code>systemd</code>経由で実行されるスクリプトは、<code>StandardOutput=syslog</code>と<code>StandardError=syslog</code>により<code>journalctl</code>にログが記録されます。</p></li>
<li><p>必要に応じて、スクリプト内で<code>logger</code>コマンドを使用したり、特定のログファイルにリダイレクトしたりして、詳細なログを記録します。</p></li>
<li><p>定期実行タスクの成功・失敗を監視し、失敗時には通知する仕組み(例: Prometheus/Grafana, Zabbix, Datadogなどと連携)を構築します。</p></li>
</ul>
<h3 class="wp-block-heading">4.3 コード管理とデプロイ</h3>
<ul class="wp-block-list">
<li><p>スクリプトはGitなどのバージョン管理システムで管理します。</p></li>
<li><p>CI/CDパイプラインに組み込み、テストを経て本番環境にデプロイするプロセスを確立します。</p></li>
</ul>
<h2 class="wp-block-heading">5. トラブルシュート</h2>
<h3 class="wp-block-heading">5.1 一般的な問題</h3>
<ul class="wp-block-list">
<li><p><strong>PHPメモリ制限</strong>: <code>wp-cli</code>は、WordPressが使用するPHPメモリ制限を超過することがあります。<code>php.ini</code>の<code>memory_limit</code>を増やすか、<code>wp-cli.yml</code>ファイルで設定をオーバーライドします。</p>
<div class="codehilite">
<pre data-enlighter-language="generic"># wp-cli.yml (WordPressルートディレクトリまたはホームディレクトリ)
php:
memory_limit: 512M
</pre>
</div></li>
<li><p><strong>データベース接続エラー</strong>: データベースのクレデンシャル、ホスト、ポートが正しいか確認します。<code>wp-config.php</code>の設定と<code>wp-cli</code>の実行ユーザーからの接続性をチェックします。</p></li>
<li><p><strong>ファイル権限エラー</strong>: WordPressのファイルやディレクトリの所有者と権限が正しく設定されているか確認します。<code>wp-cli</code>を実行するユーザーが、WordPressのファイルシステムに対する読み書き権限を持っている必要があります。</p></li>
<li><p><strong>wp-cliのパス</strong>: スクリプト内で<code>wp</code>コマンドをフルパス(例: <code>/usr/local/bin/wp</code>)で指定するか、実行環境の<code>PATH</code>環境変数に<code>wp</code>コマンドのディレクトリが含まれていることを確認します。</p></li>
<li><p><strong><code>systemd</code>ログにエラーがないか</strong>: <code>journalctl -u your-service.service</code> で詳細なログを確認します。</p></li>
</ul>
<h3 class="wp-block-heading">5.2 デバッグのヒント</h3>
<ul class="wp-block-list">
<li><p>スクリプトを<code>bash -x script.sh</code>で実行し、どのコマンドが実行されているかトレースします。</p></li>
<li><p><code>systemd</code>サービスを手動で<code>sudo systemctl start your-service.service</code>で実行し、その直後に<code>journalctl -u your-service.service -e</code>でログの末尾を確認します。</p></li>
<li><p><code>systemd</code>ユニットファイルから<code>User=</code>や<code>Group=</code>の設定を一時的に削除し、<code>root</code>で実行して権限の問題ではないか切り分けます(本番環境では非推奨)。</p></li>
</ul>
<h2 class="wp-block-heading">6. まとめ</h2>
<p><code>wp-cli</code>は、WordPressサイトのコマンドライン管理において不可欠なツールです。本記事で紹介した<code>set -euo pipefail</code>や<code>trap</code>を用いた安全なBashスクリプト、<code>jq</code>と<code>curl</code>による外部連携、そして<code>systemd unit/timer</code>による堅牢な定期実行の仕組みを導入することで、WordPressの運用を大幅に自動化し、安定性、信頼性、効率性を向上させることができます。</p>
<p>これらの実践を通じて、DevOpsエンジニアとしてWordPress環境の管理スキルをさらに高め、より複雑なデプロイメントや運用の課題に対応できるようになるでしょう。</p>
<hr/>
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
wp-cliでWordPressサイトをコマンドライン管理
1. 要件と前提
WordPressサイトの管理は、GUIベースのダッシュボードを通じて行うのが一般的ですが、DevOpsの文脈では、構築、更新、バックアップ、デプロイなどの繰り返し作業を自動化し、安定性と効率性を高めることが求められます。wp-cliは、WordPressをコマンドラインから管理するための強力なツールであり、これらの自動化要件を満たす鍵となります。
1.1 要件
wp-cliを活用したWordPressサイトのコマンドライン管理手法を理解する。
自動化スクリプトは冪等(idempotent)であること。
安全なbashスクリプトの記述方法(set -euo pipefail, trap, 一時ディレクトリの利用)を習得する。
JSONデータ処理にjqを、外部API連携にcurlを安全に利用する。
systemd unitとsystemd timerを用いて定期的な自動実行を設定する。
root権限の扱いと権限分離に関するセキュリティ上の注意点を理解する。
1.2 前提環境
Linux OS (例: Ubuntu, CentOS)
PHP (WordPressの要件に準拠、CLI版も必要)
MySQL/MariaDBまたは互換性のあるデータベース
NginxまたはApacheなどのWebサーバー
wp-cliがインストールされていること
jq, curlがインストールされていること
2. 実装
2.1 wp-cliのインストール
wp-cliは、bashスクリプトを通じてインストールするのが推奨されています。これにより、常に最新の安定版を導入できます。
#!/bin/bash
# wp-cliインストールスクリプト
set -euo pipefail
WP_CLI_BIN_PATH="/usr/local/bin/wp" # wp-cli実行ファイルのパス
# wp-cliが既に存在するか確認し、存在しなければダウンロード・配置
if ! command -v wp &>/dev/null; then
echo "wp-cliをダウンロードしています..."
curl -o /tmp/wp-cli.phar https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
if [[ ! -f /tmp/wp-cli.phar ]]; then
echo "エラー: wp-cli.pharのダウンロードに失敗しました。" >&2
exit 1
fi
chmod +x /tmp/wp-cli.phar
sudo mv /tmp/wp-cli.phar "$WP_CLI_BIN_PATH"
echo "wp-cliが $WP_CLI_BIN_PATH にインストールされました。"
else
echo "wp-cliは既にインストールされています。"
fi
# シェルのPATHにwp-cliのパスが含まれているか確認
if ! echo "$PATH" | grep -q "$(dirname "$WP_CLI_BIN_PATH")"; then
echo "警告: wp-cliのパス ($(dirname "$WP_CLI_BIN_PATH")) がPATHに含まれていません。"
echo "手動で追加するか、フルパスで実行してください。"
fi
# インストール確認
wp --info
参照: WP-CLI公式ドキュメント – Installing WP-CLI [^1] (最終確認日: 2024年7月26日 JST)
2.2 安全なBashスクリプトの記述
自動化スクリプトは、予期せぬエラーで停止したり、不完全な状態で終了したりしないように、堅牢に記述する必要があります。
以下の例は、WordPressのデータベースをバックアップし、不要なリビジョンをクリーンアップするスクリプトです。
#!/bin/bash
# WordPressデータベースバックアップ&最適化スクリプト
set -euo pipefail
# --- 変数定義 ---
WP_PATH="/var/www/html/wordpress" # WordPressのルートディレクトリ
BACKUP_DIR="/var/backups/wordpress_db"
DB_USER="wp_user"
DB_PASS="your_db_password" # 環境変数やシークレット管理ツールで扱うのがより安全
# --- 一時ディレクトリの設定とクリーンアップ ---
# mktemp -dは一時ディレクトリを作成し、そのパスを出力する
TMP_DIR=$(mktemp -d -t wp-db-XXXXXXXX)
# trapでスクリプト終了時に一時ディレクトリを削除
trap 'echo "一時ディレクトリ ${TMP_DIR} を削除しています..."; rm -rf "${TMP_DIR}"' EXIT
# --- 作業ディレクトリへの移動と権限確認 ---
if [[ ! -d "$WP_PATH" ]]; then
echo "エラー: WordPressディレクトリ $WP_PATH が見つかりません。" >&2
exit 1
fi
cd "$WP_PATH" || { echo "エラー: WordPressディレクトリに移動できませんでした。" >&2; exit 1; }
# WordPressのファイルオーナーと実行ユーザーが異なる場合、sudo -uで実行
# 例: Webサーバーユーザー (www-data) でwp-cliを実行
# sudo -u www-data wp ...
# または、スクリプト実行ユーザーに適切な権限を付与する。
# ここではスクリプト実行ユーザーがwp-cliを実行できる前提。
# --- バックアップディレクトリの作成 ---
mkdir -p "$BACKUP_DIR"
# --- データベースのバックアップ ---
echo "WordPressデータベースをバックアップしています..."
BACKUP_FILE="${BACKUP_DIR}/wordpress_db_$(date +%Y%m%d_%H%M%S).sql"
# wp db export コマンドは、デフォルトで.sqlファイルを標準出力に出力しない。
# 直接ファイルに書き込むオプションも持つが、一時ファイル経由も安全。
if wp db export "${TMP_DIR}/current_db.sql" --user="$DB_USER" --pass="$DB_PASS" --path="$WP_PATH"; then
mv "${TMP_DIR}/current_db.sql" "$BACKUP_FILE"
echo "データベースバックアップが $BACKUP_FILE に保存されました。"
else
echo "エラー: データベースのバックアップに失敗しました。" >&2
exit 1
fi
# --- データベースの最適化とクリーンアップ ---
echo "WordPressデータベースを最適化し、不要なリビジョンをクリーンアップしています..."
# 投稿リビジョンを最新の3つ以外削除
# dry-runで確認後、--yesで実行
wp post delete $(wp post list --post_type='revision' --format=ids --allow-root | head -n -3) --force --path="$WP_PATH" --yes
# wp post list --post_type='revision' --format=ids --path="$WP_PATH" | xargs -r wp post delete --force --path="$WP_PATH" --yes # こちらの方がより安全
# 上記コマンドはpost_type='revision'の投稿をすべて取得し、そのうち最後の3つを残して削除する。
# 特定のpost_idを削除するのではなく、リビジョンを削除する場合は `wp revisions delete` を使用するほうが正確。
# 例: wp revisions clean --keep=3 --path="$WP_PATH"
# 今回は一般的なクリーンアップとして wp post delete で代替
# もしくは wp option update "blog_public" 0 でサイトを一時的に非公開にするなども検討
# データベースの最適化
if wp db optimize --path="$WP_PATH"; then
echo "データベースの最適化が完了しました。"
else
echo "警告: データベースの最適化中に問題が発生した可能性があります。" >&2
fi
echo "WordPressデータベースの管理スクリプトが正常に完了しました。"
2.3 jq を用いたJSON処理と curl の利用
wp-cliの多くのコマンドは--format=jsonオプションでJSON形式の出力を生成できます。これをjqで処理することで、複雑な情報を抽出したり、他のシステムと連携したりできます。curlは、外部の監視サービスへの通知や、WordPressサイトの可用性チェックなどに利用できます。
#!/bin/bash
# WordPressプラグインの更新と通知スクリプト
set -euo pipefail
# --- 変数定義 ---
WP_PATH="/var/www/html/wordpress"
WEBHOOK_URL="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX" # 通知先Webhook URL
SITE_URL="https://your-wordpress-site.com"
# --- 作業ディレクトリへの移動 ---
cd "$WP_PATH" || { echo "エラー: WordPressディレクトリに移動できませんでした。" >&2; exit 1; }
# --- プラグインの更新チェックと更新 ---
echo "利用可能なプラグインの更新を確認しています..."
# wp plugin update --all は、更新があるプラグインのみを更新するため冪等
# --dry-run でまず確認することもできる
UPDATE_OUTPUT=$(wp plugin update --all --format=json --allow-root)
# --allow-root はDocker環境などで必要になることがあるが、通常運用では非推奨。
# 特定のユーザー (例: www-data) で実行するべき。 sudo -u www-data wp plugin update ...
UPDATED_PLUGINS=$(echo "$UPDATE_OUTPUT" | jq -r '.[] | select(.update_status == "Success") | .name')
if [[ -z "$UPDATED_PLUGINS" ]]; then
MESSAGE="WordPressのプラグインに利用可能な更新はありませんでした。"
echo "$MESSAGE"
else
MESSAGE="WordPressプラグインが更新されました:\n${UPDATED_PLUGINS}"
echo -e "$MESSAGE"
fi
# --- サイトの健全性チェックと通知 (curl) ---
echo "サイトの可用性をチェックしています..."
# curlのオプション:
# -sS: Silent but show errors
# --retry 5: 5回までリトライ
# --retry-delay 3: リトライ間の待機時間 (秒)
# --retry-connrefused: 接続拒否でもリトライ
# --max-time 10: 最大10秒でタイムアウト
# --fail-early: 最初の失敗ですぐに終了 (リトライと組み合わせると少し挙動が変わる)
# --output /dev/null: 出力を破棄
# --resolve: DNSルックアップをオーバーライドする (テスト環境などで便利)
if curl -sS --retry 5 --retry-delay 3 --retry-connrefused --max-time 10 --output /dev/null "$SITE_URL"; then
STATUS_MESSAGE="WordPressサイト (${SITE_URL}) は正常に動作しています。"
echo "$STATUS_MESSAGE"
else
STATUS_MESSAGE="エラー: WordPressサイト (${SITE_URL}) が利用できません。または応答が遅延しています。"
echo "エラー: $STATUS_MESSAGE" >&2
# Webhook通知にエラーメッセージを追加
MESSAGE="${MESSAGE}\n${STATUS_MESSAGE}"
fi
# --- Slack Webhookへの通知 ---
if [[ -n "$WEBHOOK_URL" ]]; then
echo "Slackに通知を送信しています..."
# jqでJSONペイロードを生成
PAYLOAD=$(jq -n --arg msg "$MESSAGE" '{text: $msg}')
# curlでWebhookにPOST
# -H "Content-Type: application/json": JSON形式で送信
# -X POST: POSTメソッド
# -d @- : 標準入力からデータを読み込む (PAYLOAD変数をechoでパイプ)
if echo "$PAYLOAD" | curl -sS -H "Content-Type: application/json" -X POST -d @- "$WEBHOOK_URL"; then
echo "通知が正常に送信されました。"
else
echo "エラー: Slackへの通知に失敗しました。" >&2
fi
fi
echo "WordPressプラグイン更新と通知スクリプトが完了しました。"
2.4 systemd unit/timer の利用
systemdはLinuxシステムでサービスやタスクを管理するための強力なツールです。timerとunitを組み合わせることで、cronのような定期実行タスクをより柔軟かつ詳細に管理できます。
以下の例では、上記で作成したデータベースバックアップスクリプトを毎日午前2時に実行する設定を示します。
フロー図: systemdによるWordPress自動バックアップ
graph TD
A["systemd timer: wp-db-backup.timer"] -->|毎朝2:00にトリガー| B("systemd service: wp-db-backup.service")
B -->|サービス起動| C["Bashスクリプト: wp-db-backup.sh"]
C -->|wp-cliコマンド実行| D("WordPress DBバックアップ")
C -->|wp-cliコマンド実行| E("WordPress DB最適化")
C -->|終了ステータスを返却| B
B -->|ログ出力| F[journalctl]
2.4.1 サービスユニットファイル (/etc/systemd/system/wp-db-backup.service)
[Unit]
Description=WordPress Database Backup and Optimization
Documentation=https://your-documentation-link.com
# After=network-online.target はネットワークが必要な場合に指定
# 今回はDBへのアクセスなので不要な場合も
[Service]
Type=oneshot
# ExecStartPreはExecStartの前に実行されるコマンド
# これにより、スクリプト実行前に必要な環境変数を設定したり、ログディレクトリを作成したりできる
# ExecStart=/bin/bash -c "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /path/to/your/wp-db-backup.sh"
# 環境変数を明示的に設定してスクリプトを実行
ExecStart=/bin/bash -c 'WP_PATH="/var/www/html/wordpress" /usr/local/bin/wp-db-backup.sh'
# 環境変数をスクリプト内で定義済みの場合は、単純にスクリプトパスを指定
# ExecStart=/usr/local/bin/wp-db-backup.sh
# User と Group を指定することで、指定されたユーザー権限でスクリプトが実行される
# これにより、root権限での実行を避け、最小権限の原則を適用できる
# 例: Webサーバーを実行しているユーザーを指定 (例: www-data, nginx)
User=www-data
Group=www-data
# WorkingDirectory はスクリプトが実行されるカレントディレクトリを設定
# スクリプト内で cd している場合は不要だが、設定しておくとより明確
WorkingDirectory=/var/www/html/wordpress
# RestartPolicy は、サービスが失敗した場合の再起動ポリシーを定義
# 今回のType=oneshotの場合、OnFailureが適切
Restart=on-failure
RestartSec=5s # 5秒後に再起動を試みる
# StandardOutputとStandardErrorでログの出力先を制御
# syslogに送信 (journalctlで確認可能)
StandardOutput=syslog
StandardError=syslog
# PrivateTmp=true: サービス専用の一時ディレクトリを作成し、終了時に自動削除
PrivateTmp=true
[Install]
WantedBy=multi-user.target
注意: ExecStart のパスは、スクリプトの実装場所に合わせ、User と Group はWordPressが動作するユーザーに合わせてください。wp-db-backup.sh スクリプトのパスも適切に更新する必要があります(例: /usr/local/bin/wp-db-backup.sh に配置)。
2.4.2 タイマーユニットファイル (/etc/systemd/system/wp-db-backup.timer)
[Unit]
Description=Run WordPress Database Backup and Optimization daily
[Timer]
# OnCalendarはタイマーを起動する日時を指定
# "daily": 毎日
# "hourly": 毎時
# "*-*-* 02:00:00": 毎日午前2時 (システムが起動していれば)
OnCalendar=*-*-* 02:00:00
# Persistent=true: システム停止中に期限が過ぎた場合、起動後にすぐに実行される
# (OnCalendarで指定された最後の実行時刻を記憶)
Persistent=true
# AccuracySec=1h: 起動時刻の精度を1時間単位にする(リソース節約)
# 厳密な時刻が必要な場合はコメントアウトするか、より短い時間を設定
AccuracySec=1h
[Install]
WantedBy=timers.target
2.4.3 systemd設定の適用と起動
スクリプトの配置:
wp-db-backup.sh を /usr/local/bin/ など適切な場所に配置し、実行権限を付与します。
sudo cp wp-db-backup.sh /usr/local/bin/wp-db-backup.sh
sudo chmod +x /usr/local/bin/wp-db-backup.sh
ユニットファイルの配置:
上記の.serviceと.timerファイルを/etc/systemd/system/に配置します。
systemdのリロード:
新しいユニットファイルを認識させるためにsystemdをリロードします。
sudo systemctl daemon-reload
タイマーの起動と有効化:
sudo systemctl enable wp-db-backup.timer # システム起動時にタイマーが有効になるようにする
sudo systemctl start wp-db-backup.timer # 今すぐタイマーを開始する
3. 検証
設定したsystemdタイマーが正しく動作しているか確認します。
タイマーの状態確認:
systemctl list-timers | grep wp-db-backup
出力例:
NEXT LEFT LAST PASSED UNIT ACTIVATES
Fri 2024-07-27 02:00:00 JST 13h left Thu 2024-07-26 02:00:00 JST 11h ago wp-db-backup.timer wp-db-backup.service
NEXTとLASTの時刻を確認し、LEFTが次回実行までの時間を示していることを確認します。
サービスのテスト実行:
タイマーの実行を待たずに、手動でサービスを実行して動作を確認できます。
sudo systemctl start wp-db-backup.service
ログの確認:
実行後のログをjournalctlで確認します。
journalctl -u wp-db-backup.service --since "1 day ago"
スクリプトのecho出力がここに記録されます。エラーメッセージがないか、バックアップファイルが正しく作成されているか確認します。
バックアップファイルの確認:
BACKUP_DIRに指定したディレクトリ(例: /var/backups/wordpress_db/)にバックアップファイルが作成されていることを確認します。
4. 運用
4.1 権限管理とroot権限の扱い
最小権限の原則: wp-cliスクリプトは、WordPressファイルとデータベースにアクセスする権限を持つ最小限のユーザーで実行すべきです。Webサーバーが動作するユーザー(例: www-data, nginx)を指定するのが一般的です。systemdのUser=およびGroup=ディレクティブを活用します。
root権限の回避: wp-cliコマンドに--allow-rootオプションは極力使用を避けるべきです。開発環境や特殊なコンテナ環境以外で本番環境で使うことは推奨されません。
データベースパスワード: データベースユーザーのパスワードは、スクリプトに直接記述せず、環境変数、またはwp-cliの設定ファイル(wp-cli.yml)、あるいはSecret Managementツール(HashiCorp Vault, AWS Secrets Managerなど)で管理することを強く推奨します。
4.2 ロギングとモニタリング
systemd経由で実行されるスクリプトは、StandardOutput=syslogとStandardError=syslogによりjournalctlにログが記録されます。
必要に応じて、スクリプト内でloggerコマンドを使用したり、特定のログファイルにリダイレクトしたりして、詳細なログを記録します。
定期実行タスクの成功・失敗を監視し、失敗時には通知する仕組み(例: Prometheus/Grafana, Zabbix, Datadogなどと連携)を構築します。
4.3 コード管理とデプロイ
5. トラブルシュート
5.1 一般的な問題
PHPメモリ制限: wp-cliは、WordPressが使用するPHPメモリ制限を超過することがあります。php.iniのmemory_limitを増やすか、wp-cli.ymlファイルで設定をオーバーライドします。
# wp-cli.yml (WordPressルートディレクトリまたはホームディレクトリ)
php:
memory_limit: 512M
データベース接続エラー: データベースのクレデンシャル、ホスト、ポートが正しいか確認します。wp-config.phpの設定とwp-cliの実行ユーザーからの接続性をチェックします。
ファイル権限エラー: WordPressのファイルやディレクトリの所有者と権限が正しく設定されているか確認します。wp-cliを実行するユーザーが、WordPressのファイルシステムに対する読み書き権限を持っている必要があります。
wp-cliのパス: スクリプト内でwpコマンドをフルパス(例: /usr/local/bin/wp)で指定するか、実行環境のPATH環境変数にwpコマンドのディレクトリが含まれていることを確認します。
systemdログにエラーがないか: journalctl -u your-service.service で詳細なログを確認します。
5.2 デバッグのヒント
スクリプトをbash -x script.shで実行し、どのコマンドが実行されているかトレースします。
systemdサービスを手動でsudo systemctl start your-service.serviceで実行し、その直後にjournalctl -u your-service.service -eでログの末尾を確認します。
systemdユニットファイルからUser=やGroup=の設定を一時的に削除し、rootで実行して権限の問題ではないか切り分けます(本番環境では非推奨)。
6. まとめ
wp-cliは、WordPressサイトのコマンドライン管理において不可欠なツールです。本記事で紹介したset -euo pipefailやtrapを用いた安全なBashスクリプト、jqとcurlによる外部連携、そしてsystemd unit/timerによる堅牢な定期実行の仕組みを導入することで、WordPressの運用を大幅に自動化し、安定性、信頼性、効率性を向上させることができます。
これらの実践を通じて、DevOpsエンジニアとしてWordPress環境の管理スキルをさらに高め、より複雑なデプロイメントや運用の課題に対応できるようになるでしょう。
コメント