ノートPCのスリープでOpenHandsの長時間タスクが中断する。
最短解は、個人用PCを公開せず、独立したリモートVMにAgent Canvasを置き、私用ネットワークで確認してからAPIキー、TLS、保活、サンドボックスを追加することです。

この記事は、OpenHandsを継続稼働させたい個人開発者、チーム共有用のAgent Serverを用意するプラットフォーム・DevOps担当者、XcodeやmacOS向けビルドを遠隔化したい開発責任者向けです。macOS固有のツールチェーンが不要なら、まずLinux VMだけで十分です。

最終更新:2026年8月14日。コマンド、公開方法、認証、構成は、OpenHands公式リポジトリのREADME、公式セルフホスト手順、Agent Canvasのリリース一覧を同日に確認しています。

OpenHands Agent CanvasのリモートVM導入を始める前に

最初に決めるのは、VMのサイズではなく「Agentにどこまで触らせるか」です。OpenHandsの公式構成では、Agent Canvasが画面、Agent Serverが複数Agentを実行するREST API、Automation Backendがスケジュールやイベント起点の処理、作業ディレクトリが実際のリポジトリを担います。Agent Canvasは複数のAgent Serverへ接続して切り替えられます。

独立VMを個人開発機より優先する理由は3つあります。

  • ノートPCのスリープ、Wi-Fi切断、再起動で長時間タスクが止まりにくいこと。
  • 個人のSSH鍵、ブラウザー設定、未整理の環境変数と、Agentが触る作業領域を分離できること。
  • VMを壊して再作成する運用にしやすく、失敗したAgentの変更を開発機へ直接持ち込まずに済むこと。

一方、ホスト上で直接動かす構成は、Agentがホストのファイルシステム、環境、ネットワークへアクセスできるため、Dockerサンドボックスより強い分離にはなりません。OpenHandsの公式アーキテクチャ資料でも、ホスト上での直接実行ではファイルアクセス範囲が広くなり得ると説明されています。(公式アーキテクチャ資料)

実行境界は次の3つに分けてください。

  1. VMはAgent CanvasとAgent Serverだけを動かす。
  2. VM自身でリポジトリをビルドし、テストする。
  3. 必要に応じて、Dockerサンドボックスや別の構築ノードへ処理を渡す。

通常のコード解析、Webサービスのテスト、Linux向けバックエンドのビルドはVMに置きます。Xcode、iOSシミュレーター、Apple署名、macOS専用SDKが必要な処理だけを遠隔Macへ分けるのが安全です。

第1段階:私用ネットワークだけで最小構成を起動する

クラウドサーバーへ入れるか

Agent Canvasは、常時稼働するLinuxまたはmacOSホスト、クラウドVM、専用機へ配置できます。公式のVM手順では、Ubuntu 24.04 LTSを例に、Node.js 22.x、curl、git、uvを準備します。これは公式手順に記載された構成例であり、すべての作業量に対する下限値とは扱わないでください。

まずファイアウォールではSSHだけを自分のIPまたはVPNのCIDRに限定します。Agent Canvasの内部サービスを、最初から外部へ公開しないことが重要です。

sudo apt-get update
sudo apt-get install -y curl git
curl -LsSf https://astral.sh/uv/install.sh | sh

Node.jsは公式READMEが示す22.12.x以降を使用します。Node.jsの導入方法は、nvm、asdf、NodeSourceなど、運用環境で管理しやすい方法を選びます。

SSH接続を維持したまま、ローカルPCからトンネルを張ります。

ssh -N -L 8000:127.0.0.1:8000 user@your-vm

その後、VM上で最小起動します。

export LOCAL_BACKEND_API_KEY=$(openssl rand -base64 32)
npx @openhands/agent-canvas --public

公式セルフホスト手順では、このコマンドが静的フロントエンド、Agent Server、Automation Backendを起動し、127.0.0.1:8000のIngressで経路をまとめます。--publicを付けるとAPIキーをフロントエンドへ埋め込まず、画面で入力させる構成になります。(公式セルフホスト手順)

初回の合格条件は、画面が開くだけでは不十分です。次の4点を確認します。

  • http://localhost:8000で画面が表示される。
  • Agent Serverが接続済みとして表示される。
  • 対象リポジトリを読み取れる。
  • 短いタスクを送り、実行イベントが継続して返る。

第2段階:Agent Serverと作業領域の境界を固定する

Agent Serverを公開する場合、APIキーは単なる画面ログイン用の文字列ではありません。APIリクエストにX-Session-API-Keyヘッダーを付け、対応するLOCAL_BACKEND_API_KEYと照合する構成では、キーの漏えいがAgent操作やホスト上のファイル操作につながる可能性があります。

APIキーは、公開リポジトリ、フロントエンドの静的ファイル、チャットログ、CIの標準出力へ書き込まないでください。環境変数、秘密管理サービス、権限を絞ったsystemd設定など、運用者だけが読める場所で管理します。

直接実行とDockerサンドボックスの判断は、次のように分けます。

  • 直接実行:構築が簡単ですが、AgentがVMの環境やネットワークへ広く触れます。単一用途の使い捨てVM向けです。
  • Dockerサンドボックス:プロジェクト用ディレクトリを明示的にマウントでき、開発機や共有VMの被害範囲を抑えやすくなります。ただし、Dockerソケットや広すぎるボリュームを渡すと分離効果が弱まります。

Docker版では、PROJECTS_PATHにAgentが扱うプロジェクト群を置き、設定ディレクトリと作業ディレクトリを分けてマウントします。プロジェクトディレクトリを明示してコンテナへ渡す構成は、公式READMEの例でも示されています。

本番前には、次の境界テストを実行します。

  • 許可したリポジトリ以外を読み取れないか。
  • 不正なAPIキーでAPI操作が拒否されるか。
  • 秘密ファイルや不要な環境変数がAgentから見えないか。
  • 危険な削除、外部送信、権限変更の指示を受けた場合に、実行範囲が想定内に収まるか。

第3段階:SSH切断と再起動に耐える保活を入れる

SSHが切れてもタスクを継続させる構成

SSHの切断を防ぐだけならtmuxで足ります。

export LOCAL_BACKEND_API_KEY='保存済みのキー'
tmux new-session -d -s canvas 'npx @openhands/agent-canvas --public'

ただし、長期運用ではsystemdを優先します。SSHが切れた場合だけでなく、プロセス異常終了やホスト再起動から戻す責任を、端末セッションではなくOSのサービス管理へ移せるためです。公式セルフホスト手順でも、長期運用ではsystemdを使う構成が案内されています。

[Unit]
Description=Agent Canvas
After=network.target

[Service]
Environment=LOCAL_BACKEND_API_KEY=保存済みのキー
ExecStart=/usr/bin/npx @openhands/agent-canvas --public
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

実際のnpxの場所は、command -v npxで確認してから設定してください。

sudo systemctl daemon-reload
sudo systemctl enable --now agent-canvas
sudo systemctl status agent-canvas

保活の合格条件は、プロセスが存在することではありません。実行中のタスクがイベントを返し続けること、サービス再起動後に画面から再接続できること、ログが無制限に増えないこと、ホスト再起動後に自動復帰することまで確認します。

第4段階:公開アクセスにTLSとリバースプロキシを追加する

公開アクセスを安全にする設定

私用ネットワークでの確認が済んだ後、外出先やチームから使う場合だけドメインとHTTPSを追加します。公式構成では、nginxがTLSを終端し、内部の127.0.0.1:8000へ転送します。Agent Server、Automation Backend、静的サーバーの内部ポートを外部へ直接公開する構成にはしません。

外部ファイアウォールの考え方は次の通りです。

  • SSHの22番は自分のIPまたはVPNに限定する。
  • HTTPの80番は証明書発行に必要な場合だけ許可する。
  • HTTPSの443番は、可能ならIP許可リストまたはVPNに限定する。
  • 内部サービスのポートは外部から遮断する。

nginxでは、リアルタイムイベントのためにWebSocketまたはSSEを通せる設定が必要です。

location / {
    proxy_pass http://127.0.0.1:8000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;
}

HTTPS化後は、HTTPがHTTPSへリダイレクトされること、APIキー入力画面が表示されること、イベント接続が途中で切れないこと、証明書の自動更新タイマーが有効なことを確認します。

第5段階:ローカル画面からリモートバックエンドへ切り替える

ローカル画面とリモートAgent Serverの使い分け

手元のAgent Canvasを残したまま、リモートVMを追加バックエンドとして登録できます。管理画面のバックエンド追加でホスト名、https://の接続先、Session API Keyを入力し、接続済みになったバックエンドへ切り替えます。SSHトンネルを使う場合は、ローカル側からhttp://localhost:8000を指定します。

ここで注意したいのは、バックエンドの切り替えがコード同期を意味しないことです。ローカルで未コミットの変更をリモートVMが自動的に読むわけではありません。Gitでブランチを共有する、必要なファイルだけ転送する、またはリモート側で作業ブランチをチェックアウトする手順を決めてください。

リモートVMを共有するなら、チームごとに作業ディレクトリ、APIキー、Git認証情報を分けます。単一の強いキーを全員で使うと、誰がどのAgentを起動したかを追跡しにくくなります。

公開前の可否判定と遠隔Macの追加条件

OpenHandsで遠隔Macを使うタイミング

普通のコード分析、Webサービスの動作確認、Linux向けビルドなら、まずLinux VMへ残します。遠隔Macが必要になるのは、Xcode、macOS SDK、iOSシミュレーター、Apple署名、macOSネイティブアプリなど、Linux VMでは同じ成果物を作れない場合です。

OpenHandsは、Agent ServerをクラウドVMだけでなくMac Miniのような専用機にも配置でき、Agent Canvasから複数のAgent Serverを切り替える構成に対応しています。

遠隔Macを追加する前に、次のチェックを完了してください。

  • [ ] Linux VMでリポジトリの取得、解析、テストが完了する
  • [ ] SSH切断後もAgent Canvasのプロセスが継続する
  • [ ] VM再起動後にサービスが自動復帰する
  • [ ] APIキーなしのアクセスが拒否される
  • [ ] 許可外ディレクトリと秘密情報を読み取れない
  • [ ] 実行イベントを最後まで受信できる
  • [ ] 実際のリポジトリで同時実行時の競合を確認する
  • [ ] Xcodeや署名が必要な処理だけを遠隔Macへルーティングする

macOSの構築ノードを継続利用する場合は、遠隔Macの開発環境選びも確認してください。Linux VMでは代替できないツールチェーンが明確で、再起動復旧とビルド成果物の回収まで検証できた場合に限り、Macノードを増やす価値があります。

現在の構成とSSHMacの遠隔環境を比較する

手元のノートPCだけで運用する方法は、追加費用を抑えられる一方、スリープ、ネットワーク切断、個人環境への権限集中という弱点があります。Linux VMだけの構成は長時間タスクと一般的な開発に向きますが、XcodeやApple署名を実行できません。自前のMacを常時稼働させる方法は自由度が高い反面、電源、保守、再起動、外部公開の管理まで自分で負担します。

一時的な検証環境や、既存VMではmacOSツールチェーンだけ足りないケースでは、SSHMacの遠隔Macを追加する方が、専用機の購入や個人PCの公開より判断しやすい場合があります。まずLinux VMを標準バックエンドにし、必要なリポジトリだけをMacノードへ送る運用なら、コストと権限範囲を分けて評価できます。利用条件を整理したい場合は、Macレンタルプランの選び方を見ながら、Xcode、署名、シミュレーターの要件を照合してください。