AI 用の仮想マシンの様子を、家のトップページの一番上に出す ― 負荷・メモリと、中で動くものの状態を5分ごとに
家のサーバーの上で、AI 専用の仮想マシン(vm1)を動かしています(AI エージェント用の仮想マシンを作った話)。中では4つの AI と Orca が常に動き、メールのまとめや AI の使用状況の集計もここで行っています(仕事を引っ越した話)。
仕事が増えるほど、「今ちゃんと動いているか」が気になります。そこで、家のトップページの一番上に、vm1 の様子を出す欄を作りました。負荷・メモリ・ディスクの数字と、中で動いているものの状態が、色の丸で一目で分かります。この記事では、欄の見方と仕組みをまとめます。作業は、いつもどおり AI(Claude Code)に言葉で頼んで進めました。

1. 欄の見方
上の段は数字、下の段は中で動いているものの状態です。右上には、最後に様子を集めた時刻が出ます。
| 項目 | 何を見ているか |
|---|---|
| 負荷(1分) | 直近1分の忙しさ。「0.00 / 4コア」なら、4つあるうちほとんど使っていない |
| 起動してから | 最後に起動してからの時間。急に短くなっていたら、知らないうちに再起動している |
| メモリ使用・ディスク使用 | 使っている割合と量を、数字と棒グラフで |
| Orca | AI に作業を頼む Orca のサーバー(画面なしで常に動く)が動いているか |
| 画面(VNC) | vm1 のデスクトップの画面(Mac などから見る用)が動いているか |
| ブラウザで画面 | その画面をブラウザで開くための部品(noVNC)が動いているか |
| Obsidian へのトンネル | vm1 の AI がノートを読み書きするための、Mac からの専用の通り道がつながっているか |
| Vault の写し | ノートの保管場所の読み取り専用の写し(準備中のため、今は「まだ無し」) |
| メールのまとめ | 15分ごとのメールのまとめが、最後に終わった時刻 |
| 使用状況の集計 | 5分ごとの AI の使用状況の集計が、最後に終わった時刻 |
丸の色は3つです。
- 緑:動作中、または決まった間隔のうちに処理が終わっている(メールのまとめは30分以内、使用状況の集計は15分以内)
- 黄:しばらく処理が動いていない、まだ一度も動いていない、またはトンネルが切れている(「切断」と出る)
- 赤:サービスが止まっている
さらに、様子そのものが15分以上新しくならないと、右上に「(更新が止まっています)」と出ます。vm1 が固まった・止まったときは、これで気づけます。
2. 仕組み:vm1 が集め、家のサーバーが取りに行く

vm1:5分ごとに様子を1つのファイルにまとめる
vm1 では、Python の小さなスクリプトを cron(決まった時刻にコマンドを動かす仕組み)で5分ごとに動かし、様子を JSON(データを書くための決まった書き方)のファイルにまとめます。見ているのは次の3種類です。
- 数字:負荷・起動してからの時間・メモリ・ディスク(Linux の
/procなどから読む) - サービス:
systemctl is-activeで、Orca・画面・noVNC が動いているか - 処理の時刻:メールのまとめなどが最後に書いたファイルの更新時刻
トンネルだけは、vm1 の中からは「Mac が張ってくれた通り道の入口が開いているか」で見ています。
def port_open(port):
out = subprocess.run(["ss", "-ltn"], capture_output=True, text=True).stdout
return f"127.0.0.1:{port} " in out
"obsidian_tunnel": "active" if port_open(XXXX) else "inactive",
家のサーバー:決まったファイルを返すだけの鍵で取りに行く
家のサーバーは、5分ごとに vm1 へ SSH して、そのファイルを受け取ります。このとき使う鍵は、vm1 の側で「決まったファイルの中身を返す」ことしかできないようにしてあります。
# vm1 の ~/.ssh/authorized_keys(鍵は1行)
restrict,command="/home/agent/bin/serve_topdata.sh" ssh-ed25519 AAAA... home-server
# serve_topdata.sh:頼まれた名前のファイルを返すだけ
case "$SSH_ORIGINAL_COMMAND" in
mail) cat "$HOME/topdata/mail_summary.json" ;;
vm) cat "$HOME/topdata/vm_status.json" ;;
*) cat "$HOME/ai_usage/vm1.json" ;;
esac
メールのまとめや AI の使用状況も、同じ鍵・同じ方法で受け取っています。vm1 からは家のサーバーに入れません。AI に確認なしで作業させても、vm1 の外を壊せないようにするためです。つながりはどれも「外から vm1 へ」の向きにしてあります。
受け取ったファイルは、JSON として読めて、中の名前が vm1 のときだけ表示用の場所に置きます。vm1 が止まっていて取れなかったときは、前回の内容を残します。前回の時刻が古くなっていくので、トップページの「更新が止まっています」で気づける、という形です。
3. 「画面を開く」ボタン
欄の見出しの横の「画面を開く(Orca など)」を押すと、vm1 のデスクトップの画面がブラウザで開きます。vm1 に入れた noVNC(VNC の画面をブラウザで見るための部品)を使っていて、家の中と VPN からだけ開けます。開くときは VNC のパスワードが要ります。
どの端末からでも、アプリを入れずに vm1 の Orca に作業を頼めるようにしたくて付けました。iPad からはアプリでも見られます(iPad から Mac と家のサーバーを操作する)。
4. 役に立った場面
- vm1 が固まったとき:11月4日の夜、vm1 がネットワークに応答しなくなりました。欄の最後の正常な記録が 22:20 だったので、いつから止まっていたかがすぐに分かりました。強制リセットで戻しました
- Mac が止まったとき:トンネルが黄色の「切断」になるので、vm1 の AI がノートを読み書きできない状態だと分かります
まとめ
- vm1 が5分ごとに自分の様子をまとめ、家のサーバーが取りに行ってトップページに出す
- 取りに行く鍵は「決まったファイルを返す」だけ。vm1 からはどこにも入れない
- 色の丸と「更新が止まっています」で、止まったことにすぐ気づける
- 「画面を開く」で、どの端末からでも vm1 の画面と Orca を使える
Mac と vm1 で仕事をどう分けているかは、別の記事(Mac と AI 用の仮想マシンの役割分担)にまとめました。
