ローカルLLMと画像生成環境をMac上に構築しても、手動で操作するだけでは自動化できません。
今回の目的は、ConoHa VPS側で記事や画像の生成ジョブを登録し、自宅にあるMacBook ProまたはMac miniがその仕事を取得して処理することです。
ただし、VPSから自宅Macへ直接接続する構成にはしません。
自宅Mac側からVPSへ問い合わせる方式を採用します。
なぜVPSから直接接続しないのか
VPSから自宅Macへ直接アクセスするには、自宅側のネットワークへ外部から到達できるようにする必要があります。
その場合、次のような課題があります。
- 自宅ルーターのポート開放
- 動的IPアドレスへの対応
- NAT環境への対応
- Mac側APIの外部公開
- 認証とアクセス制限
- 不正アクセスへの対策
- 回線やルーター変更時の再設定
VPNやトンネルサービスを使う方法もありますが、今回は構成を単純にするため、自宅側を公開しません。
自宅MacからConoHa VPSへHTTPSでアクセスするだけなら、一般的なWebアクセスと同じ方向の通信になります。
ジョブを取りに行く方式
処理の流れは次のとおりです。
- 管理画面や自動処理がVPSへ生成ジョブを登録する
- Mac上のワーカーがVPSへジョブの有無を問い合わせる
- 未処理ジョブがあれば取得する
- ローカルLLMまたはComfyUIで生成する
- 結果をVPSへ返す
- VPSがジョブを完了状態にする
この方式では、VPSは自宅MacのIPアドレスや接続先を知る必要がありません。
Mac側が自分から通信できれば動作します。
通常ポーリングとロングポーリング
Macがジョブを確認する方法として、通常ポーリングとロングポーリングがあります。
通常ポーリング
一定時間ごとに短いリクエストを送ります。
例えば30秒間隔なら、次の動作になります。
- Macがジョブの有無を問い合わせる
- ジョブがなければ空の応答を受け取る
- 30秒待つ
- 再び問い合わせる
1台あたり1日2,880回のリクエストになりますが、小さなJSONを返すだけなら、個人利用のVPSでは大きな負荷にはなりにくい回数です。
ロングポーリング
今回採用するのはロングポーリングです。
Macがジョブ取得APIへアクセスすると、VPSはジョブが登録されるまで一定時間リクエストを保持します。
例えば最大30秒待機する場合は次のようになります。
- Macがジョブ取得APIへ接続する
- すでにジョブがあればすぐ返す
- ジョブがなければ最大30秒待つ
- 待機中にジョブが登録されたら即座に返す
- 30秒経過してもジョブがなければ空の応答を返す
- Macはすぐに次の接続を開始する
これにより、ジョブが登録されてから処理開始までの待ち時間を短くできます。
WebSocketほど接続管理が複雑ではなく、通信が切れても再接続しやすい点も利点です。
VPS側の構成
初期構成では、VPS側に次の要素を用意します。
- FastAPI
- PostgreSQL
- ジョブ登録API
- ジョブ取得API
- ハートビートAPI
- 結果送信API
- 管理用ログ
ジョブの内容はPostgreSQLへ保存します。
初期段階では、専用のメッセージキュー製品を追加せず、PostgreSQLで管理します。
ワーカー数がMacBook ProとMac miniの2台であり、個人運用の規模であれば、まずは十分対応できると考えています。
ジョブに保存する情報
ジョブには、少なくとも次の情報を持たせます。
- ジョブID
- ジョブ種別
- 入力内容
- 状態
- 優先度
- 作成日時
- 処理開始日時
- 完了日時
- 担当ワーカー
- 最終ハートビート時刻
- 再試行回数
- エラー内容
- 生成結果の保存先
ジョブ種別には、例えば次の値を使用します。
- article_generate
- article_rewrite
- article_summary
- image_generate
- image_upscale
記事と画像で必要な入力形式が異なるため、ジョブ種別ごとに入力内容を検証します。
Mac側のワーカー
Mac上では、Python製のワーカーを常駐させます。
ワーカーの役割は次のとおりです。
- VPSへロングポーリングする
- ジョブを取得する
- ジョブ種別を確認する
- OllamaまたはComfyUIを呼び出す
- 処理中にハートビートを送る
- 結果をVPSへ送信する
- 次のジョブを待つ
OllamaやComfyUIを外部へ公開する必要はありません。
Pythonワーカーが同じMac内のローカルAPIへ接続します。
認証
MacからVPSへ接続する際には、ワーカーごとに異なる認証情報を使用します。
例えば、MacBook ProとMac miniへそれぞれ次の識別情報を割り当てます。
- worker-mbp
- worker-macmini
さらに、それぞれ別のAPIキーを発行します。
APIキーはソースコードに直接書かず、環境変数やmacOSのキーチェーンなどで管理します。
VPS側では、次の内容を記録します。
- どのワーカーが接続したか
- どのジョブを取得したか
- 処理にどれくらい時間がかかったか
- エラーが発生したか
- 不自然な回数のアクセスがないか
生成結果の返し方
記事生成結果はJSONとしてVPSへ返せます。
画像はファイルサイズが大きくなるため、次のいずれかの方法を使用します。
- 結果送信APIへ直接アップロード
- VPS側で一時アップロードURLを発行
- オブジェクトストレージへアップロード
- PayloadのメディアAPIへVPS経由で登録
初期構成では、MacからVPSへ画像を送り、VPS側でPayloadへ登録します。
これにより、Payloadの認証情報を自宅Macへ置かずに済みます。
まとめ
VPSから自宅Macへ直接接続せず、Mac側がジョブを取りに行く構成にすることで、自宅回線を外部へ公開せずに生成処理を自動化できます。
通信方式には30秒待機のHTTPSロングポーリングを使用します。
次回は、MacBook ProとMac miniが同時に接続した場合の二重処理や、Macが途中で停止した場合の復旧方法を設計します。