wp-cli を用いたWordPressサイトの自動管理

Tech

本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

wp-cli を用いたWordPressサイトの自動管理

要件と前提

WordPressサイトの維持管理において、コア、プラグイン、テーマの定期的なアップデートはセキュリティと機能性を保つ上で不可欠です。しかし、手動での作業は手間がかかり、ミスが発生する可能性もあります。本記事では、wp-cli を活用し、これらの管理タスクを自動化するためのDevOpsアプローチについて解説します。

目的:

  • WordPressコア、プラグイン、テーマの定期的な自動アップデート。

  • アップデート結果の自動通知。

  • 処理の idempotent (冪等) 性と安全性確保。

対象読者:

  • WordPressサイトを多数運用しているDevOpsエンジニア。

  • WordPressの自動管理に関心のあるシステム管理者。

前提条件:

  • Linux環境 (Ubuntu/CentOSなど) でのWordPress運用経験。

  • wp-clijqcurlsystemd の基本的な知識。

  • スクリプト実行権限のある非 root ユーザーが存在すること。

セキュリティと権限分離: 自動化スクリプトは、システム上で重要な操作を実行します。そのため、セキュリティと権限分離は最優先事項です。スクリプトは root ユーザーではなく、WordPressが動作するウェブサーバーのユーザー(例: www-data)または専用の低権限ユーザー(例: wpuser)で実行することを強く推奨します。sudo の使用は最小限にとどめ、必要なコマンドにのみ許可するように設定すべきです。

実装

WordPressサイトの自動管理スクリプトは、以下のフローで動作します。

graph TD
    A["Systemd Timerが起動"] --> B("WordPress更新スクリプト実行")
    B --> C{"WP-CLIで更新チェックと健全性確認"}
    C -- 更新あり & 健全 --> D["WP-CLI Core/Plugin/Theme更新"]
    C -- 更新なし or 不健全 --> E("処理完了")
    D --> F{"更新成功?"}
    F -- 成功 --> G("更新結果をJSON出力")
    F -- 失敗 --> H("エラーログ記録")
    G --> I["jqでJSONパースし、通知メッセージを生成"]
    I --> J["curlで通知APIへ結果を送信"]
    H --> J
    J --> K("スクリプト終了")

安全なBashスクリプトの基本

自動化スクリプトは、予期せぬエラーで処理が中断されないよう、安全な書き方を徹底します。

#!/bin/bash


# スクリプトの実行設定


# -e: コマンドが失敗した場合、即座に終了


# -u: 未定義の変数を使用しようとした場合、エラーとする


# -o pipefail: パイプライン中のコマンドが一つでも失敗した場合、パイプライン全体を失敗とする

set -euo pipefail

# 一時ディレクトリの作成とクリーンアップ


# mktemp -d: 一意な名前の一時ディレクトリを作成


# trap: スクリプト終了時に指定したコマンドを実行 (EXIT, ERR, INT, TERMシグナル)

TMP_DIR=$(mktemp -d)
trap 'rm -rf "$TMP_DIR"' EXIT ERR INT TERM # スクリプト終了時またはエラー時に一時ディレクトリを削除

# ログファイルの設定

LOG_FILE="/var/log/wp-updates/wordpress_update_$(date +%Y%m%d_%H%M%S).log"
mkdir -p "$(dirname "$LOG_FILE")"
exec > >(tee "$LOG_FILE") 2>&1 # 標準出力と標準エラーをログファイルとコンソールに同時に出力

echo "--- WordPress自動更新スクリプト開始: $(date +'%Y-%m-%d %H:%M:%S JST') ---"

# WordPressインストールパス (環境に合わせて変更)

WP_PATH="/var/www/wordpress"

# WP-CLIコマンドを特定のユーザーで実行するための関数


# 必要に応じてsudo -u <user>で実行

run_wp_cli() {

    # 例: WordPressがwww-dataユーザーで動作している場合


    # sudo -u www-data wp "$@" --path="$WP_PATH"


    # または、スクリプト自体がそのユーザーで実行される場合

    wp "$@" --path="$WP_PATH"
}

このスクリプトは、2024年7月27日 JSTに作成されました。set -euo pipefail はスクリプトの堅牢性を高め、trap コマンドは一時ディレクトリの確実なクリーンアップを保証します [3]。

WordPress自動更新スクリプトの作成

主要な更新処理を記述します。更新前にはヘルスチェックを行い、問題があれば更新をスキップするなどの安全性確保が重要です。

# ... (前述の安全なBashスクリプトの基本部分) ...

# ヘルスチェックの実施

echo "WordPressサイトのヘルスチェックを開始..."
HEALTH_STATUS_JSON=$(run_wp_cli health check status --format=json)
HEALTH_CRITICAL_ISSUES=$(echo "$HEALTH_STATUS_JSON" | jq -r '.critical_issues')

if [ "$HEALTH_CRITICAL_ISSUES" -ne 0 ]; then
    echo "警告: サイトに致命的な問題があります ($HEALTH_CRITICAL_ISSUES 件)。更新をスキップします。"
    echo "$HEALTH_STATUS_JSON" | jq .
    exit 1
fi
echo "ヘルスチェックは問題ありませんでした。"

# WordPressコアの更新

echo "WordPressコアの更新を確認..."
CORE_STATUS=$(run_wp_cli core check-update --format=json)
if echo "$CORE_STATUS" | jq -e '.[0].update_type == "minor" or .[0].update_type == "major"' > /dev/null; then
    echo "WordPressコアを更新します..."
    run_wp_cli core update --skip-content-check --allow-root # --allow-rootは推奨されないため、systemdのUser設定で代替が望ましい
    echo "WordPressコアのデータベース更新を実行..."
    run_wp_cli core update-db
    CORE_UPDATE_RESULT="SUCCESS"
else
    echo "WordPressコアは最新です。"
    CORE_UPDATE_RESULT="SKIPPED"
fi

# プラグインの更新

echo "プラグインの更新を確認..."
PLUGIN_UPDATES=$(run_wp_cli plugin list --update=available --format=json)
if echo "$PLUGIN_UPDATES" | jq -e '.[]' > /dev/null; then
    echo "利用可能なプラグインを更新します..."

    # --allでまとめて更新。個別に更新する場合はループ

    run_wp_cli plugin update --all
    PLUGIN_UPDATE_RESULT="SUCCESS"
else
    echo "すべてのプラグインは最新です。"
    PLUGIN_UPDATE_RESULT="SKIPPED"
fi

# テーマの更新

echo "テーマの更新を確認..."
THEME_UPDATES=$(run_wp_cli theme list --update=available --format=json)
if echo "$THEME_UPDATES" | jq -e '.[]' > /dev/null; then
    echo "利用可能なテーマを更新します..."
    run_wp_cli theme update --all
    THEME_UPDATE_RESULT="SUCCESS"
else
    echo "すべてのテーマは最新です。"
    THEME_UPDATE_RESULT="SKIPPED"
fi

UPDATE_STATUS=$(jq -n \
    --arg core "$CORE_UPDATE_RESULT" \
    --arg plugin "$PLUGIN_UPDATE_RESULT" \
    --arg theme "$THEME_UPDATE_RESULT" \
    '{ "timestamp": "$(date +%Y-%m-%d %H:%M:%S JST)", "core": $core, "plugins": $plugin, "themes": $theme }')

echo "--- WordPress自動更新スクリプト終了: $(date +'%Y-%m-%d %H:%M:%S JST') ---"
echo "更新結果: $UPDATE_STATUS"

# ... (通知処理へ続く) ...

wp-cli は、WordPressの管理タスクをコマンドラインから実行できる強力なツールです。core updateplugin update --alltheme update --all などを用いて、WordPressの各コンポーネントを更新します [1]。

jqによるJSON処理例

wp-cli の多くのコマンドは --format=json オプションでJSON形式の出力を生成できます。jq を使用して、このJSONデータをパースし、必要な情報を抽出します。

# ... (前述のスクリプトから続く) ...

# 例: 更新結果JSONから通知メッセージを生成

NOTIFICATION_MESSAGE=$(echo "$UPDATE_STATUS" | jq -r \
    '"WordPress更新レポート (\(.timestamp)): Core: \(.core), Plugins: \(.plugins), Themes: \(.themes)"')

echo "通知メッセージ: $NOTIFICATION_MESSAGE"

# ... (curlによる通知処理へ続く) ...

jq はJSON形式のデータを柔軟に処理するための強力なコマンドラインツールです。例えば、jq -r '.key' で特定の値を取得したり、複合的なオブジェクトを生成したりできます [6]。

curlによるAPI連携例 (通知)

更新結果をSlackやMattermostなどのチャットツール、または監視システムに通知するために curl を使用します。TLS検証、再試行メカニズムを含めることで、ネットワークの信頼性が低い場合でも堅牢性を高めます。

# ... (前述のスクリプトから続く) ...

# 通知先のWebhook URL (例: Slack, Mattermost)

WEBHOOK_URL="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"

# curlで通知を送信

echo "通知APIへ結果を送信します..."
if curl \
    --fail \
    --silent \
    --show-error \
    --retry 5 \
    --retry-delay 3 \
    --retry-max-time 30 \
    --connect-timeout 5 \
    --max-time 10 \
    --cacert /etc/ssl/certs/ca-certificates.crt \
    -X POST \
    -H "Content-Type: application/json" \
    -d "{\"text\": \"${NOTIFICATION_MESSAGE}\"}" \
    "$WEBHOOK_URL"; then
    echo "通知を正常に送信しました。"
else
    echo "エラー: 通知の送信に失敗しました。" >&2
fi

exit 0

curl コマンドには、--retry (再試行回数)、--retry-delay (再試行間隔)、--retry-max-time (最大再試行時間) といった堅牢なネットワーク処理のためのオプションがあります。また、--cacert でTLS証明書の検証を行うことでセキュリティを確保します [5]。

systemdユニット/タイマーの設定

作成したBashスクリプトを定期的に実行するために systemd のユニットとタイマーを設定します。

1. スクリプトの配置

作成したスクリプトを /usr/local/bin/wordpress-update.sh などに配置し、実行権限を付与します。

sudo install -m 755 wordpress-update.sh /usr/local/bin/wordpress-update.sh

2. systemdサービスユニットファイル (.service) の作成

/etc/systemd/system/wordpress-update.service を作成します。

[Unit]
Description=Automated WordPress Update Service
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
User=www-data # WordPressが動作するユーザーを指定
Group=www-data # WordPressが動作するグループを指定
WorkingDirectory=/var/www/wordpress # WordPressのルートディレクトリ
ExecStart=/usr/local/bin/wordpress-update.sh

# ログはjournaldに統合されるため、不要であればスクリプト内のログ出力を抑制可能

StandardOutput=journal
StandardError=journal

# 実行時間制限 (例: 10分)

TimeoutStartSec=600

[Install]
WantedBy=multi-user.target

UserGroup ディレクティブは、スクリプトを指定したユーザーとグループの権限で実行するために重要です。これにより、root 権限での不必要な実行を防ぎ、権限分離を促進します [4]。

3. systemdタイマーユニットファイル (.timer) の作成

/etc/systemd/system/wordpress-update.timer を作成します。

[Unit]
Description=Run WordPress Update Script Daily

[Timer]

# 毎日午前3時30分に実行 (JST)

OnCalendar=*-*-* 03:30:00

# システム起動後30秒後に初回実行(システム起動時に実行したい場合)


# OnBootSec=30s


# サービスの実行失敗時にタイマーを再起動

Persistent=true

[Install]
WantedBy=timers.target

OnCalendar オプションで実行スケジュールを設定します。上記の例では毎日午前3時30分 JSTに実行されます [4]。

4. systemdユニットの有効化と起動

# systemdに新しいユニットファイルを認識させる

sudo systemctl daemon-reload

# サービスとタイマーを有効化

sudo systemctl enable wordpress-update.service
sudo systemctl enable wordpress-update.timer

# タイマーを起動

sudo systemctl start wordpress-update.timer

検証

設定したスクリプトと systemd ユニットが正しく動作するか検証します。

  1. スクリプトの単体テスト: sudo -u www-data /usr/local/bin/wordpress-update.sh (またはWordPressが動作するユーザーで実行) ログファイル (/var/log/wp-updates/) と通知先のメッセージを確認します。

  2. systemdサービスの起動テスト: sudo systemctl start wordpress-update.service sudo systemctl status wordpress-update.service で成功したことを確認します。 journalctl -u wordpress-update.service でサービスが生成したログを確認します。

  3. systemdタイマーの動作確認: sudo systemctl list-timers | grep wordpress-update タイマーが有効になっており、次回の実行時刻が表示されていることを確認します。LAST 列と NEXT 列をチェックします。

運用

  • ログ監視: journalctl -u wordpress-update.service で定期的にログを監視します。エラーメッセージや警告に注意し、必要に応じてスクリプトを改善します。

  • エラーハンドリングとアラート: スクリプトの通知機能が機能していることを確認し、通知が届かない場合はcurlの設定やネットワーク状況を確認します。通知サービスがダウンしている場合を考慮し、他の監視ツールとの連携も検討します。

  • 定期的なレビューと改善: WordPressのバージョンアップやWP-CLIの機能追加に合わせて、スクリプトやsystemd設定を定期的にレビューし、改善します。

  • 権限管理のベストプラクティス: wordpress-update.sh スクリプトは最小限の権限で実行されるべきです。www-data ユーザーの権限が広すぎる場合は、専用の wpuser などを作成し、WordPressディレクトリへの書き込み権限のみを与えることを検討してください。

トラブルシュート

  • スクリプトが実行されない:

    • systemctl status wordpress-update.timer でタイマーがアクティブになっているか確認。

    • systemctl status wordpress-update.service でサービスが正常終了しているか、エラーがないか確認。

    • journalctl -u wordpress-update.service でサービスログの詳細を確認。

    • スクリプトファイルの実行権限 (chmod +x) を確認。

    • ExecStart のパスが正しいか確認。

  • WP-CLIコマンドが失敗する:

    • WordPressのパス (WP_PATH) が正しいか確認。

    • User= で指定したユーザーがWordPressディレクトリへの書き込み権限を持っているか確認 (sudo -u www-data ls -l /var/www/wordpress)。

    • WP-CLIが正しくインストールされ、PATH が通っているか確認。

  • 通知が届かない:

    • curl コマンドのWEBHOOK_URLが正しいか確認。

    • ネットワーク接続を確認。

    • curl コマンドの --fail オプションにより、エラーが発生している可能性があるので、詳細なエラーメッセージをログから確認。

まとめ

wp-clisystemd タイマーと組み合わせることで、WordPressサイトの管理作業を効果的に自動化できます。本記事で紹介した安全なBashスクリプトの書き方、jqcurl を用いた連携、そして適切な権限分離の考慮は、堅牢で信頼性の高い自動化システムを構築するための基盤となります。これらのアプローチを取り入れることで、DevOpsエンジニアは運用負荷を軽減し、より重要なタスクに集中できるようになるでしょう。


参考文献: [1] WP-CLI Docs. (2024年7月25日更新). WP-CLI Handbook. WP-CLI maintainers. https://wp-cli.org/docs/ [2] schlessera. (2024年7月10日公開). Release v2.9.0. GitHub. https://github.com/wp-cli/wp-cli/releases/tag/v2.9.0 [3] Linux Foundation. (2023年10月20日更新). Bash Scripting Guide. https://training.linuxfoundation.org/resources/open-source-guides/bash-scripting-guide/ [4] systemd project. (2024年5月15日更新). systemd.timer man page. https://www.freedesktop.org/software/systemd/man/systemd.timer.html [5] Daniel Stenberg. (2024年7月26日更新). curl man page. https://curl.se/docs/manpage.html#OPTIONS [6] stedolan et al. (2024年6月1日更新). jq Manual. https://jqlang.github.io/jq/manual/

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

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