Agentive
副業・収益化

AI WordPress保守で月額収入 — サイト管理の自動化サービス

約5分で読めます

AI WordPress保守で月額収入

WordPressの保守を自動化し、月額5,000-30,000円のサブスクリプション収入を得る。サイト管理の大半は定型作業であり、AIとスクリプトで自動化すれば1人で50サイト以上を管理できる。

サービスメニューと月額単価

プラン月額内容
ライト5,000円バックアップ + 更新通知
スタンダード15,000円バックアップ + 自動更新 + セキュリティ監視
プレミアム30,000円全自動管理 + 月次レポート + 障害対応

50サイト(平均1万円/月)を管理すれば月50万円の安定収入となる。

バックアップ自動化

import subprocess
import boto3
from datetime import datetime

def backup_wordpress(site_config: dict):
    """WordPressサイトのフルバックアップを取得してS3に保存"""
    site = site_config["domain"]
    ssh = site_config["ssh"]
    timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")

    # データベースバックアップ
    db_file = f"/tmp/{site}-db-{timestamp}.sql.gz"
    subprocess.run([
        "ssh", ssh,
        f"mysqldump -u {site_config['db_user']} -p{site_config['db_pass']} "
        f"{site_config['db_name']} | gzip > /tmp/db-backup.sql.gz"
    ], check=True)
    subprocess.run(["scp", f"{ssh}:/tmp/db-backup.sql.gz", db_file], check=True)

    # ファイルバックアップ
    files_archive = f"/tmp/{site}-files-{timestamp}.tar.gz"
    subprocess.run([
        "ssh", ssh,
        f"tar czf /tmp/files-backup.tar.gz -C {site_config['wp_path']} ."
    ], check=True)
    subprocess.run(["scp", f"{ssh}:/tmp/files-backup.tar.gz", files_archive], check=True)

    # S3にアップロード
    s3 = boto3.client("s3")
    for filepath in [db_file, files_archive]:
        s3.upload_file(filepath, "wp-backups", f"{site}/{filepath.split('/')[-1]}")

    return {"site": site, "timestamp": timestamp, "status": "success"}

セキュリティチェックリスト(自動実行)

import requests
import re
import json

class WordPressSecurityChecker:
    def __init__(self, site_url: str, ssh: str):
        self.site_url = site_url
        self.ssh = ssh

    def run_all_checks(self) -> list[dict]:
        """全セキュリティチェックを実行"""
        checks = [
            self.check_wp_version(),
            self.check_plugin_updates(),
            self.check_login_protection(),
            self.check_file_permissions(),
            self.check_ssl_certificate(),
            self.check_malware_signatures(),
        ]
        return checks

    def check_wp_version(self) -> dict:
        """WordPress本体が最新バージョンか確認"""
        resp = requests.get(self.site_url)
        version_match = re.search(r'content="WordPress (\d+\.\d+\.?\d*)"', resp.text)
        current = version_match.group(1) if version_match else "unknown"
        latest = requests.get(
            "https://api.wordpress.org/core/version-check/1.7/"
        ).json()
        latest_ver = latest["offers"][0]["version"]
        return {
            "check": "wp_version",
            "status": "OK" if current == latest_ver else "UPDATE_NEEDED",
            "current": current, "latest": latest_ver
        }

    def check_plugin_updates(self) -> dict:
        """更新が必要なプラグインを検出"""
        result = subprocess.run(
            ["ssh", self.ssh, "wp plugin list --update=available --format=json"],
            capture_output=True, text=True
        )
        outdated = json.loads(result.stdout) if result.stdout else []
        return {
            "check": "plugin_updates",
            "status": "OK" if len(outdated) == 0 else "UPDATE_NEEDED",
            "outdated_count": len(outdated),
            "plugins": [p["name"] for p in outdated]
        }

    def check_login_protection(self) -> dict:
        """ログインページの保護状態を確認"""
        resp = requests.get(f"{self.site_url}/wp-login.php")
        has_captcha = "recaptcha" in resp.text.lower() or "hcaptcha" in resp.text.lower()
        return {
            "check": "login_protection",
            "status": "OK" if has_captcha else "WARN",
            "detail": "CAPTCHA検出" if has_captcha else "CAPTCHA未設定"
        }

    def check_file_permissions(self) -> dict:
        """危険なファイルパーミッションを検出"""
        result = subprocess.run(
            ["ssh", self.ssh, "find /var/www/html -perm -o+w -type f | head -20"],
            capture_output=True, text=True
        )
        writable = result.stdout.strip().split("\n") if result.stdout.strip() else []
        return {
            "check": "file_permissions",
            "status": "OK" if len(writable) == 0 else "WARN",
            "world_writable_files": len(writable)
        }

    def check_ssl_certificate(self) -> dict:
        """SSL証明書の有効期限を確認"""
        import ssl, socket
        hostname = self.site_url.replace("https://", "").replace("http://", "").split("/")[0]
        ctx = ssl.create_default_context()
        with ctx.wrap_socket(socket.socket(), server_hostname=hostname) as s:
            s.connect((hostname, 443))
            cert = s.getpeercert()
            expiry = datetime.strptime(cert["notAfter"], "%b %d %H:%M:%S %Y %Z")
            days_left = (expiry - datetime.now()).days
        return {
            "check": "ssl_certificate",
            "status": "OK" if days_left > 30 else "WARN",
            "expires_in_days": days_left
        }

    def check_malware_signatures(self) -> dict:
        """既知のマルウェアパターンをスキャン"""
        result = subprocess.run(
            ["ssh", self.ssh,
             "grep -rl 'eval(base64_decode(' /var/www/html/wp-content/ 2>/dev/null | head -5"],
            capture_output=True, text=True
        )
        found = result.stdout.strip().split("\n") if result.stdout.strip() else []
        return {
            "check": "malware_scan",
            "status": "OK" if len(found) == 0 else "CRITICAL",
            "suspicious_files": len(found)
        }

月次レポート自動生成

from anthropic import Anthropic

client = Anthropic()

def generate_monthly_report(site: str, checks: list, backup_log: list) -> str:
    """AIで月次保守レポートを生成"""
    report_data = {
        "site": site,
        "period": "2026年3月",
        "security_checks": checks,
        "backups_completed": len(backup_log),
        "backup_success_rate": sum(
            1 for b in backup_log if b["status"] == "success"
        ) / len(backup_log) * 100
    }

    response = client.messages.create(
        model="claude-haiku-4-5-20250901",
        max_tokens=800,
        messages=[{
            "role": "user",
            "content": f"""
            以下のデータからWordPress保守の月次レポートを作成してください。
            クライアント向けの丁寧な文面で、専門用語は避けてください。

            データ: {json.dumps(report_data, ensure_ascii=False)}

            含める内容:
            - 今月の保守サマリ
            - セキュリティ状況
            - バックアップ状況
            - 実施した更新作業
            - 来月の推奨アクション
            """
        }]
    )
    return response.content[0].text

運用スケジュール

頻度作業
毎日バックアップ実行、死活監視
週次セキュリティスキャン、プラグイン更新チェック
月次全項目チェック + レポート生成・送付
四半期パフォーマンス監査、PHP/DBバージョン確認

顧客獲得の流れ

  1. 「WordPress保守を自動化したい」中小企業をターゲットにする
  2. 初月無料のセキュリティ診断で信頼を獲得する
  3. 診断結果をもとに保守プランを提案する
  4. 自動化により対応工数を最小化し、利益率70%以上を維持する

まとめ

WordPress保守は「バックアップ + セキュリティ + レポート」の3要素を自動化することで、1人で数十サイトを管理できるスケーラブルなビジネスモデルになる。月額のストック収入は事業の安定基盤となる。

関連記事

A

Agentive 編集部

AIエージェントを実際に使い倒す個人開発者。サイト制作の自動化を実践しながら、その知見を発信しています。