2026年9月24日

2026年9月24日

WP-CLIを使ったWordPress運用の自動化テクニック【シェルスクリプト活用】

はじめに

WP-CLIはWordPressをコマンドラインから操作できるツールです。プラグインの一括更新、データベースの操作、コンテンツ管理をシェルスクリプトと組み合わせることで、定期メンテナンスを完全自動化できます。手動作業によるミスをなくし、運用コストを大幅に削減しましょう。

症状・原因

  • プラグインの更新を忘れてセキュリティリスクが高まっている
  • 毎回手動でバックアップするのが手間でスキップしてしまう
  • 大量の投稿やユーザーを一括操作したいが管理画面では限界がある
  • サーバーのcronでWordPress独自の定期処理を制御したい

解決手順

ステップ1:必須WP-CLIコマンドの習得

WP-CLIの基本コマンドを覚えることで、日常的な管理作業を高速化できます。

# WP-CLIのインストール(まだの場合)
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

# バージョン確認
wp --version

# WordPress本体の更新
wp core update
wp core update-db

# プラグインの一括更新
wp plugin update --all

# テーマの一括更新
wp theme update --all

# 更新が必要なプラグイン一覧を確認
wp plugin list --update=available --format=table

# データベースのエクスポート(日付付きファイル名)
wp db export /var/backups/db-$(date +%Y%m%d).sql

# キャッシュのフラッシュ
wp cache flush

# リライトルールの再生成
wp rewrite flush --hard

--path=/var/www/htmlオプションを使えば、どのディレクトリからでも特定のWordPressを操作できます。複数サイトを運用している場合に便利です。

ステップ2:自動バックアップシェルスクリプトの作成

データベースとファイルを自動でバックアップするスクリプトを作成します。

#!/bin/bash
# /usr/local/bin/wp-backup.sh
# WordPress自動バックアップスクリプト

set -euo pipefail

# 設定
WP_PATH="/var/www/html"
BACKUP_DIR="/var/backups/wordpress"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/wp-backup.log"

# ログ関数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# バックアップディレクトリ作成
mkdir -p "${BACKUP_DIR}/${DATE}"

log "バックアップ開始: ${DATE}"

# データベースのエクスポート
log "データベースをエクスポート中..."
wp --path="$WP_PATH" db export "${BACKUP_DIR}/${DATE}/database.sql" \
    --allow-root 2>> "$LOG_FILE"

# ファイルのバックアップ(wp-contentのみ)
log "wp-contentをバックアップ中..."
tar -czf "${BACKUP_DIR}/${DATE}/wp-content.tar.gz" \
    -C "$WP_PATH" wp-content \
    --exclude="wp-content/cache" \
    2>> "$LOG_FILE"

# 圧縮
gzip -f "${BACKUP_DIR}/${DATE}/database.sql"

log "バックアップ完了: $(du -sh ${BACKUP_DIR}/${DATE} | cut -f1)"

# 古いバックアップを削除
find "$BACKUP_DIR" -maxdepth 1 -type d -mtime "+${RETENTION_DAYS}" -exec rm -rf {} \;
log "古いバックアップを削除しました(${RETENTION_DAYS}日以上前)"

# メンテナンス完了後にアップデート
log "プラグインを更新中..."
wp --path="$WP_PATH" plugin update --all --allow-root >> "$LOG_FILE" 2>&1

log "バックアップ・更新処理完了"
# スクリプトに実行権限を付与
chmod +x /usr/local/bin/wp-backup.sh

# テスト実行
/usr/local/bin/wp-backup.sh

ステップ3:投稿の一括操作

大量の投稿やコメントを効率的に管理する方法です。

# 投稿一覧を取得(下書き)
wp post list --post_status=draft --format=table

# 特定カテゴリの投稿IDを取得してCSV出力
wp post list \
    --post_type=post \
    --post_status=publish \
    --category_name="未分類" \
    --fields=ID,post_title,post_date \
    --format=csv > /tmp/posts.csv

# 古い下書き投稿を一括削除(90日以上前)
wp post list \
    --post_status=draft \
    --date_query='[{"column":"post_modified","before":"90 days ago"}]' \
    --format=ids | xargs wp post delete --force

# テスト用投稿を100件生成
wp post generate --count=100 --post_type=post --post_status=publish

# スパムコメントを一括削除
wp comment delete \
    $(wp comment list --status=spam --format=ids) \
    --force

# ユーザーのロールを一括変更
wp user list --role=subscriber --format=ids | \
    xargs -I{} wp user update {} --role=contributor
# カスタム投稿タイプのメタデータを一括更新
wp post list --post_type=product --format=ids | while read ID; do
    wp post meta update $ID _price "1000"
    echo "Updated post $ID"
done

ステップ4:カスタムWP-CLIコマンドの作成

独自のビジネスロジックをWP-CLIコマンドとして実装します。

<?php
// /wp-content/mu-plugins/custom-cli-commands.php
// Must Use Plugin として自動ロード

if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
    return;
}

/**
 * カスタムサイトメンテナンスコマンド
 */
class My_Site_CLI_Command {

    /**
     * 孤立したポストメタを削除する
     *
     * ## EXAMPLES
     *
     *     wp mysite cleanup-orphan-meta
     *     wp mysite cleanup-orphan-meta --dry-run
     *
     * @when after_wp_load
     */
    public function cleanup_orphan_meta( $args, $assoc_args ) {
        global $wpdb;
        
        $dry_run = WP_CLI\Utils\get_flag_value( $assoc_args, 'dry-run', false );
        
        $orphan_meta = $wpdb->get_results(
            "SELECT meta_id, post_id, meta_key 
             FROM {$wpdb->postmeta} pm
             LEFT JOIN {$wpdb->posts} p ON pm.post_id = p.ID
             WHERE p.ID IS NULL"
        );
        
        $count = count( $orphan_meta );
        WP_CLI::log( "孤立したポストメタ: {$count} 件" );
        
        if ( $dry_run ) {
            WP_CLI::success( "ドライラン完了。実際には削除していません。" );
            return;
        }
        
        foreach ( $orphan_meta as $meta ) {
            delete_metadata_by_mid( 'post', $meta->meta_id );
        }
        
        WP_CLI::success( "{$count} 件の孤立メタデータを削除しました。" );
    }

    /**
     * サイトの健全性レポートを表示する
     *
     * @when after_wp_load
     */
    public function health_report( $args, $assoc_args ) {
        WP_CLI::log( "=== サイト健全性レポート ===" );
        WP_CLI::log( "WordPressバージョン: " . get_bloginfo( 'version' ) );
        WP_CLI::log( "アクティブテーマ: " . get_stylesheet() );
        
        $plugin_count = count( get_option( 'active_plugins', [] ) );
        WP_CLI::log( "有効プラグイン数: {$plugin_count}" );
        
        global $wpdb;
        $post_count = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status='publish'" );
        WP_CLI::log( "公開済み投稿数: {$post_count}" );
        
        WP_CLI::success( "レポート完了" );
    }
}

WP_CLI::add_command( 'mysite', 'My_Site_CLI_Command' );
# カスタムコマンドを実行
wp mysite cleanup-orphan-meta --dry-run
wp mysite health-report

ステップ5:crontabでの定期実行スケジューリング

サーバーのcrontabと組み合わせて完全自動化を実現します。

# crontab の編集
crontab -e
# /etc/cron.d/wordpress-maintenance
# WordPress自動メンテナンススケジュール

MAILTO="admin@example.com"
WP_PATH="/var/www/html"
WP="/usr/local/bin/wp --path=${WP_PATH} --allow-root"

# 毎日深夜2時にバックアップ&更新
0 2 * * * root /usr/local/bin/wp-backup.sh >> /var/log/wp-backup.log 2>&1

# 1時間ごとにWordPressのcronジョブを実行
*/60 * * * * www-data $WP cron event run --due-now >> /var/log/wp-cron.log 2>&1

# 週次でデータベース最適化
0 3 * * 0 root $WP db optimize >> /var/log/wp-db.log 2>&1

# 毎時トランジェントのクリーンアップ
30 * * * * www-data $WP transient delete --expired >> /var/log/wp-cron.log 2>&1

# wp-config.php でWordPress自体のcronを無効化(サーバーcronに一本化)
# define( 'DISABLE_WP_CRON', true );
# WordPressのcronジョブ一覧確認
wp cron event list --format=table

# 特定のcronイベントを即時実行
wp cron event run wp_scheduled_delete

# カスタムcronスケジュールの登録
wp eval '
wp_schedule_event( time(), "hourly", "my_custom_cron_hook" );
echo "Cron scheduled\n";
'

# cron schedule一覧
wp cron schedule list

注意事項

  • --allow-rootオプションはrootユーザーでの実行を許可しますが、セキュリティリスクがあります。本番環境ではwww-dataなど適切なユーザーでWP-CLIを実行してください
  • wp post deleteやwp db resetなどの破壊的なコマンドはバックアップ後に実行してください。--dry-runオプションが使えるコマンドはまず確認してから実行しましょう
  • DISABLE_WP_CRONをtrueにすると、WordPressのWP-Cronが自動実行されなくなります。必ずサーバーcronでwp cron event run --due-nowを定期実行するよう設定してください

まとめ

WP-CLIとシェルスクリプトを組み合わせることで、WordPressの日常管理作業を完全自動化できます。バックアップ忘れやアップデート漏れによるセキュリティリスクを排除し、安定したサイト運用を実現しましょう。カスタムコマンドを追加することで、独自のビジネスロジックもCLIから操作できます。

関連記事:GitHub ActionsでWordPressのCI/CDパイプラインを構築する方法

お気軽にご相談ください

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