個人で運用している自律AIエージェント群(秘書+部門エージェント)のインフラ費用が、月¥0です。
VPS代もドメイン以外のサーバー代も払っていません。Cloudflare Pages(静的サイト)+ Cloudflare Tunnel + Oracle Cloud の Always Free VM に webhook を常駐させる構成で、AIが24時間タスクを拾い続けています。
ただ「無料スタックを並べました」で終わる記事は入門でよく見かけるので、この記事では実運用して初めて分かった落とし穴——Oracle のアイドル回収、PAYG(従量課金)に上げるかどうかの判断、常駐プロセスの死活監視——まで含めて、コピペで再現できる形で残します。
なぜ「¥0」にこだわったのか
本業のインフラ運用で、私は逆のことをさんざんやってきました。以前携わった案件では、日次のバッチ集計のためにEC2を24時間起動しっぱなしにしていて、実際の処理時間は1日30分程度。これをLambda(サーバーレス)に寄せたら月$50が$2になったことがあります。
この時の学びが「常時起動を疑え」でした。個人のAIエージェント組織を立てるとき、真っ先にこれを思い出しました。AIの実体は claude -p のようなヘッドレス実行と、それを叩く常駐 webhook / cron です。常に起きている必要があるのは受け口だけで、しかもその負荷はごく軽い。であれば、Always Free枠の小さなVM 1台で十分に回るはずだ、と。
結論から言うと回りました。以下が全体像です。
| レイヤー | 使うもの | 役割 | 費用 |
|---|---|---|---|
| 公開サイト | Cloudflare Pages | 静的LP・記事の配信 | ¥0 |
| 受け口 | Cloudflare Tunnel | webhookの公開(ポート開放なし) | ¥0 |
| 実行基盤 | Oracle Always Free VM | webhook常駐・cron・AI実行 | ¥0 |
| DNS/TLS | Cloudflare | ドメイン・証明書・キャッシュ | ¥0※ |
※ドメイン取得費(年1,000円前後)だけは別途。それ以外は¥0です。
1. 公開サイトは Cloudflare Pages に寄せる
静的サイト(LP・技術記事のミラー等)は Cloudflare Pages に置いています。GitHubリポジトリを繋ぐだけでプッシュのたびに自動ビルド&デプロイ、TLSも自動、帯域無制限。
以前、静的ファイルをアプリケーションサーバーから配信していて帯域を圧迫し、CDNに逃がして配信速度を3倍・転送コスト60%削減したことがあります。Pagesは最初からCDN前提なので、その最適化がデフォルトでついてくるのが個人開発では大きい。動的処理を持たないものは全部ここへ、が基本方針です。
2. webhookの受け口は Cloudflare Tunnel で通す
一番のキモがここです。AIエージェントに外部から仕事を渡すには webhook のエンドポイントが要りますが、Oracle VMのポートを直接インターネットに開けたくない。
過去に、Webサーバーのファイアウォールが未設定で3306(MySQL)や6379(Redis)が外部公開されていた現場を引き継いだことがあり、「必要なポートだけ開ける」「デフォルトで拒否」を骨身に染みて学びました。VMに穴を開ける発想自体を捨てたい。
Cloudflare Tunnel(cloudflared)はこれを解決します。VMからCloudflareへアウトバウンドの接続を張るだけで、インバウンドのポートは一切開けずに https://xxx.example.com の公開ホスト名がもらえる。
# cloudflared をインストール後、トンネルを作成
cloudflared tunnel login
cloudflared tunnel create ai-webhook
# ~/.cloudflared/config.yml
tunnel: ai-webhook
credentials-file: /home/ubuntu/.cloudflared/<TUNNEL_ID>.json
ingress:
- hostname: hook.example.com
service: http://localhost:8787 # ローカルのwebhook受け
- service: http_status:404
VMのファイアウォールはSSH以外すべて閉じたまま、webhookだけ世界に公開できます。攻撃面がSSH1つに縮むので、精神衛生上もいい。
3. Oracle Always Free VM を「常駐サーバー」にする
Oracle Cloud の Always Free には、ARM(Ampere A1)が 4 OCPU / 24GB メモリ まで無料という破格の枠があります(記事執筆時点)。個人のAIエージェント基盤には過剰なくらいです。ここに webhook受けとcronを常駐させます。
webhook常駐は systemd で(Restart=always)
最初、webhookレシーバーを nohup ... & で雑に起動していたら、ある夜にプロセスが落ちて翌朝まで受け口が死んでいました。本業でも同じ失敗をしていて、アプリプロセスの異常終了を手動再起動していた頃は夜間障害が翌朝まで復旧しなかった。systemdのRestart=alwaysに載せ替えてから、異常終了しても5秒以内に自動復帰するようになり、これはそのまま個人環境にも持ち込みました。
# /etc/systemd/system/ai-webhook.service
[Unit]
Description=AI webhook receiver
After=network.target
[Service]
ExecStart=/usr/bin/node /home/ubuntu/webhook/server.js
Restart=always
RestartSec=5
User=ubuntu
[Install]
WantedBy=multi-user.target
sudo systemctl enable --now ai-webhook
journalctl -u ai-webhook -f # ログもjournaldで一元化
cronのサイレント失敗を許さない
AIの定期実行(ネタ収集・ダイジェスト生成等)はcronで回していますが、cronは黙って失敗するのが最大の罠です。以前、15個のcronジョブのうち2つがサイレントに失敗していたのに誰も気づいていなかった現場があり、そこで「実行結果の成功/失敗を必ず通知する」を標準化しました。
個人環境でも同じルールにしています。各ジョブは終了コードを拾って結果をSlackに投げる。これをやるだけで「動いているつもりで止まっていた」が消えます。
# 実行結果を必ず通知するラッパ
run_job() {
if "$@"; then
notify "✅ $* 成功"
else
notify "🚨 $* 失敗 (exit $?)"
fi
}
run_job /home/ubuntu/jobs/collect_topics.sh
4. 落とし穴:Oracleの「アイドル回収」を心拍で回避する
ここが入門記事に載っていない部分です。Oracle の Always Free Compute は、アイドル判定されると回収(reclaim)されることがあります。おおまかな条件は「7日間のうち95%の時間でCPU使用率20%未満/ネットワーク10GB未満/メモリ20%未満」。AIの受け口は普段ほぼアイドルなので、普通に運用しているだけで回収対象になり得る。
対策として私は、本業でやっていた「毎朝のヘルスチェックをシェルスクリプト化してcronで回す」手法をそのまま流用しました。ディスク・メモリ・プロセス生存・TLS期限をチェックしてMarkdownレポートを吐く軽いスクリプトです。これを短間隔で回すと、健康診断そのものが適度な負荷(心拍)になってアイドル判定を避けられるという副次効果があります。本業ではこの自動化で年間91時間の手動確認を消しましたが、個人環境ではそれが「回収されないためのkeep-warm」を兼ねてくれました。
# /home/ubuntu/jobs/heartbeat.sh (数分おきにcron)
df -h / | tail -1
free -m | awk '/Mem/{print $3"/"$2" MB"}'
systemctl is-active ai-webhook
echo | openssl s_client -connect hook.example.com:443 2>/dev/null \
| openssl x509 -noout -enddate
PAYGに「上げない」という選択
Oracleには「Pay As You Go(従量課金)にアップグレードすればアイドル回収されなくなる」という案内があります。ただし私はあえてAlways Freeのままにしています。理由は、¥0を保証したいから。PAYGにすると回収の心配は消える代わりに、Always Free枠を1バイトでも超えた瞬間に課金が発生する——「無料のつもりが月末に請求」という事故のリスクを抱えることになる。
判断としては、
- 確実に¥0で運用したい/回収されても復旧できる → Always Free のまま+心拍でしのぐ(私はこちら)
- 絶対に落としたくない・課金は許容 → PAYGに上げて回収を止める
個人のAIエージェント基盤は「落ちても自動で建て直せる」設計にしておけば、前者で十分に戦えます。ここは結果ではなく判断そのものを共有しておきたかった部分です。
セキュリティ最低限(VM露出の観点)
Tunnelでポートを閉じても、SSHは開いています。ここは本業の鉄則をそのまま:公開鍵認証+パスワード認証無効化+fail2banの3点セット。過去にパスワード認証のままでブルートフォースのログが1日数百件記録されていた現場を、この3点でログ上ゼロにした経験があります。Always Free VMは世界中からスキャンされるので、最初にやる価値があります。
¥0スタック チートシート
| やること | 手段 | ひとことメモ |
|---|---|---|
| 静的サイト配信 | Cloudflare Pages | GitHub連携で自動デプロイ・帯域無制限 |
| webhook公開 | Cloudflare Tunnel | ポート開放ゼロ・攻撃面をSSHだけに |
| 常駐プロセス | systemd Restart=always
|
落ちても5秒で自動復帰 |
| 定期実行 | cron+結果通知ラッパ | サイレント失敗を潰す |
| アイドル回収対策 | ヘルスチェックcron(心拍) | 診断が適度な負荷を兼ねる |
| 課金事故防止 | Always Freeのまま運用 | PAYGに上げない判断も選択肢 |
| VMセキュリティ | 公開鍵+パス認証無効+fail2ban | SSHは必ず塞ぐ |
まとめ
「無料スタックを並べる」のは簡単ですが、実運用に載せると 常駐が落ちる・cronが黙って死ぬ・VMが勝手に回収される といった、入門記事には出てこない現実が待っています。面白いのは、その対策のほとんどが本業のインフラ運用で学んだ基本の焼き直しだったことです。systemdの自動再起動、cronの結果通知、ヘルスチェックの自動化、SSHの締め方——道具が無料スタックに変わっただけで、効く原則は同じでした。
月¥0でも、原則を押さえれば自律AIエージェントは十分に24時間走ります。
この記事が参考になったら、いいね・ストック していただけると励みになります。
Claude Code・AIエージェント・業務自動化まわりの実装Tipsを継続的に発信しています。フォロー しておくと新着が届きます。
みなさんは個人開発のインフラ、どこまで無料枠で寄せていますか? 「これも¥0でいけるよ」があればぜひコメントで教えてください。