OpenHandsをVPSで自ホストする方法
OpenHandsをVPSにDockerで構築する手順です。Docker socketが実質的なroot権限になる理由を確認し、Web UIとAPI keyを安全に保護します。
OpenHands の概要と、最初に理解すべき 1 つのリスク
OpenHands は、以前は OpenDevin と呼ばれていた自律型のソフトウェアエンジニアリングエージェントです。自然言語でタスクを与えると、作業を計画し、コードを作成し、コマンドを実行し、出力を読み取り、タスクが完了するまで反復します。Docker を使って自分のサーバー上で実行し、言語モデルに接続します。VPS 上では、離席中も作業するコーディングエージェントになります。
構成全体の方針を決める重要な事実があります。OpenHands はコードを提案するだけでなく、実際に実行します。そのため、コントローラーコンテナはホストの Docker socket を /var/run/docker.sock にマウントし、タスクごとにサンドボックスコンテナを起動できるようにします。Docker socket と通信できるものは、ホストのファイルシステム全体をマウントした新しいコンテナを起動できます。つまり、socket へのアクセスは実質的にマシン上の root 権限です。したがって、OpenHands を実行するサーバーは、信頼できないコードを実行するサーバーとして扱ってください。実際にそのような処理を行うためです。以下のハードニング方針は、すべてこの事実に基づいています。
必要なもの
Ubuntu 24.04 と最新の Docker Engine を実行する VPS が必要です。RAM は少なくとも 4 GB 用意してください。また、言語モデルの API key(OpenAI、Anthropic、Google のいずれか)、または 同じ VPS 上の Ollama で提供するローカルモデルが必要です。OpenHands は数十種類のモデルバックエンドをサポートしているため、選択は自由です。コンテナを設定した経験がない場合は、VPS での Docker の基礎で、このガイドが前提とする内容を確認できます。
Docker でインストールする
OpenHands は 2 つのイメージで構成されています。実行するアプリケーションイメージと、各タスクの sandbox を実行するために取得する agent-server イメージです。プロジェクトのドキュメントに記載された現在のタグに置き換えて、次のように実行します。
docker run -it --rm --pull=always \
-e AGENT_SERVER_IMAGE_REPOSITORY=ghcr.io/openhands/agent-server \
-e AGENT_SERVER_IMAGE_TAG=1.26.0-python \
-e LOG_ALL_EVENTS=true \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.openhands:/.openhands \
-p 127.0.0.1:3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands \
docker.openhands.dev/openhands/openhands:1.8混乱を避けるために、2 点確認してください。アプリケーションイメージと agent-server イメージのバージョン番号は意図的に異なります。両者を一致させようとせず、使用するアプリケーションのバージョンに対応する agent-server タグをドキュメントで確認してください。また、-p 3000:3000 ではなく -p 127.0.0.1:3000:3000 になっている点にも注意してください。この 1 つの変更により、Web UI が自分だけアクセスできる状態から、インターネット全体からアクセスできる状態に変わります。次のセクションでは、この点を説明します。
Web UI をパブリックインターネットから切り離す
OpenHands はポート 3000 でインターフェースを提供します。このインターフェースはコードを実行するエージェントを操作するため、インターネットに公開すると、見つけた誰もがコマンドを実行するプロセスへリモートアクセスできる経路を与えることになります。上記の実行コマンドと同様に loopback にバインドし、SSH トンネル経由でラップトップから接続します。
ssh -L 3000:127.0.0.1:3000 you@your-vps次に、自分のマシンで http://127.0.0.1:3000 を開きます。通信は既存の SSH セッションを通過するため、パブリックインターネット上で新たに待ち受けるものはありません。すべてのエージェントにポートが必要なわけではありません。同じ VPS 上の Claude Code セッションはターミナル経由で相互に通信するため、公開するのは SSH だけです。ホストするすべてのエージェントダッシュボードで、同じ loopback とトンネルの運用を適用する価値があります。open-kritt のスキャン UI にトンネル経由で接続する場合も同じ方法で、ポートは 5173 です。より恒久的に構成する場合は、VPN の背後に配置します。いずれの場合も、default-deny のファイアウォールをサーバーの前段に配置し、誤って何も公開しないようにします。また、IPv4 だけを対象にしたファイアウォールでは IPv6 の同じポートが開いたままになる点にも注意してください。これは多くの人が見落とす IPv6 ファイアウォールの抜け穴です。
モデルキーとリポジトリ認証情報を分離する
OpenHands では、モデル用の API key と、リポジトリの clone や push に使う token が必要になることがあります。どちらも料金が発生したり、本人として操作したりできるため、password と同じように扱ってください。これらは適切な account だけが読み取れる環境ファイルに保存してください。実行コマンドに直接記述すると、shell history と process list に残るため、記述しないでください。また、git repository 内のファイルにも保存しないでください。元の認証情報を self-hosted password manager に保管する場合は、その server も強化してください。Vault の弱点は、暗号化された項目そのものではなく、admin token と backup file になることが多いためです。詳しくは Vaultwarden の強化手順 で説明します。
破棄できるホストで実行する
コントローラーは Docker socket を保持する必要があるため、OpenHands をホストから完全にサンドボックス化することはできません。現実的な対策は、配置による分離です。データベースや Web サイトも運用しているサーバーではなく、重要なものを何も置かない専用の VPS で OpenHands を実行します。開始前に snapshot を取得し、agent が作成したコードを 1 週間実行したホストをそのまま信頼せず、その snapshot から再構築してください。安価で破棄可能な単一用途の VPS が適しています。ここで OpenHands が実際に提供する選択肢は配置だけです。そのため、agent が停止して確認を求めるまでに実行できる操作の範囲も制御したい場合は、誰も監視していないサーバーで Claude Code の permission modes を確認すると、もう 1 つの制御手段が分かります。
周囲のサーバーを堅牢化する
残りは標準的なサーバーの基本対策ですが、通常よりリスクの高いワークロードを扱うため、ここでは特に重要です。root で作業せず、権限のない管理用ユーザーを作成し、権限のないユーザーでサービスを実行するに従ってください。SSH は鍵認証のみに変更します。次に、以下のチェックリストを実行し、後でもう一度確認できる場所に保管してください。
各コマンドを実行するだけでなく、その構成要素を理解したい場合は、VPS 上で独自の AI エージェントを構築するを参照してください。コードをあまり書かないプラットフォームを使う場合は、Dify をセルフホストするのほうが取り組みやすい導入になります。
FAQ
OpenHands をサーバー上で安全に実行できますか?
注意して運用すれば可能ですが、通常の Web アプリケーションよりリスクがあります。OpenHands はコードの書き込みと実行を行い、コントローラーがホストの Docker socket を保持するためです。これは実質的にマシン上の root 権限に相当します。ほかの重要なデータを置かない、専用の使い捨て可能な VPS で実行してください。Web UI は loopback 上だけで待ち受けさせ、SSH トンネルまたは VPN 経由でアクセスします。鍵を分離し、サーバーも堅牢化してください。重要なサービスと同じサーバーでは実行しないでください。
OpenHands に Docker socket が必要なのはなぜですか?
OpenHands は各タスクを新しい sandbox container 内で実行します。controller に /var/run/docker.sock を mount して、ホストの Docker daemon にこれらの container の作成を依頼します。これにより、controller container からホスト上の Docker を制御できるようになります。この権限は強力でリスクもあるため、ホスト自体を untrusted code を実行するマシンとして扱う必要があります。
OpenHands は有料 API の代わりにローカルモデルを使用できますか?
はい。OpenHands は Ollama または vLLM が提供するローカルモデルに対応しています。そのため、token 単位の料金なしで完全に self-hosted で運用でき、データをサーバー外へ送信せずに済みます。十分な性能の coding model を実行できるだけのメモリを備えたマシンが必要です。必要なサイズの判断基準は Ollama のガイドと同じです。
OpenHands をメインサーバーで実行すべきですか?
いいえ。OpenHands は agent が作成したコードを実行し、Docker socket も保持します。そのため、再構築しても問題のない、分離した単一用途の VPS で実行してください。database、website、その他のサービスと同じサーバーに置くと、agent のミスやバグによって、本来触れるべきでない対象に到達される可能性があります。