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バージョン確認 |
顧客獲得の流れ
- 「WordPress保守を自動化したい」中小企業をターゲットにする
- 初月無料のセキュリティ診断で信頼を獲得する
- 診断結果をもとに保守プランを提案する
- 自動化により対応工数を最小化し、利益率70%以上を維持する
まとめ
WordPress保守は「バックアップ + セキュリティ + レポート」の3要素を自動化することで、1人で数十サイトを管理できるスケーラブルなビジネスモデルになる。月額のストック収入は事業の安定基盤となる。
関連記事
A
Agentive 編集部
AIエージェントを実際に使い倒す個人開発者。サイト制作の自動化を実践しながら、その知見を発信しています。