跳轉至

Openhands

Overview

Openhands(官方名稱為 OpenHands,前稱 OpenDevin)係一個開源嘅 AI 軟件開發代理平台。佢可以根據自然語言指令,自動編輯程式碼、執行終端指令、操作瀏覽器,甚至處理 GitHub issue 同 pull request。本條目係 wiki.benhoweb.com 嘅內部技術百科頁,記錄點樣以自架方式將 OpenHands 部署喺 oracle-cloud 上面。

呢個部署採用 docker-compose 管理,使用 GitHub Container Registry 嘅 ghcr.io/openhands/openhands:main 映像,並且以 agent-server 架構執行。透過 NO_SETUP=true,服務啟動後唔需要經過網頁設定精靈,直接用環境變數連接 GitHub 同模型後端。

Architecture

OpenHands 容器包含前端介面同後端 API。後端主要分為兩層:

  • app_server:負責 HTTP API、WebSocket、GitHub webhook、session 管理。
  • agent-server:負責實際嘅 coding agent 執行、sandbox 環境同工具呼叫。

喺呢個部署入面,agent-server 映像明確指定為:

AGENT_SERVER_IMAGE_REPOSITORY=ghcr.io/openhands/agent-server
AGENT_SERVER_IMAGE_TAG=main

呢個設定對應 OpenHands 新版本架構,亦支援 Oracle Cloud 常見嘅 arm64 CPU。

容器啟動時,entrypoint 會做兩個重要修補:

  1. Rate limit 修補
    sedapp.py 入面嘅 InMemoryRateLimiter(requests=10, seconds=1) 改為 requests=300, seconds=1。原本每秒 10 個 request 太容易觸發 429,尤其係 sandbox 執行 burst 或者 GitHub webhook 回調期間。改做 300 係為咗減少不必要嘅 rate limit 錯誤。

  2. Sandbox internal URL 修補
    執行 /patches/patch_sandbox_internal_url.py,修正 sandbox 內部健康檢查所用嘅 URL pattern。如果唔修,容器之間內部通訊可能因為 endpoint 格式唔啱而失敗。

修補完成之後,entrypoint 會用 exec /app/entrypoint.sh "$@" 切換到 uvicorn 啟動服務:

uvicorn openhands.server.listen:app --host 0.0.0.0 --port 3000

所以對外服務只係一個 container,但內部會按需要拉取 agent-server 映像。

Deployment

呢個服務設計係喺 Oracle Cloud VM 上自架。假設已經裝好 dockerdocker-compose,可以建立一個專案目錄,例如 ~/openhands,然後放入以下 docker-compose.yml

services:
  openhands:
    image: ghcr.io/openhands/openhands:main
    container_name: openhands
    restart: unless-stopped
    ports:
      - "3000:3000"
    entrypoint:
      - /bin/sh
      - -c
      - |
        # Patch rate limit (10 req/s -> 300 req/s) to avoid webhook 429 during sandbox bursts
        sed -i 's/InMemoryRateLimiter(requests=10, seconds=1)/InMemoryRateLimiter(requests=300, seconds=1)/' /app/openhands/app_server/app.py
        # Patch sandbox internal health-check to use internal URL pattern (see patches/)
        python3 /patches/patch_sandbox_internal_url.py
        exec /app/entrypoint.sh "$@"
      - "--"
    command:
      - uvicorn
      - openhands.server.listen:app
      - --host
      - 0.0.0.0
      - --port
      - "3000"
    environment:
      - TZ=Asia/Hong_Kong
      - NO_SETUP=true
      # 1.11.0 frontend/backend 不一致:ENABLE_AUTOMATIONS default true 但 backend 冇 automations API → /automations 頁面 crash;關閉避免 error
      - ENABLE_AUTOMATIONS=false
      # GitHub integration:PAT
      - GITHUB_TOKEN=${GITHUB_TOKEN}
      # 新版架構:main-python 支援 arm64
      - AGENT_SERVER_IMAGE_REPOSITORY=ghcr.io/openhands/agent-server
      - AGENT_SERVER_IMAGE_TAG=main

喺同一目錄建立 .env 檔案:

GITHUB_TOKEN=ghp_your_personal_access_token

然後啟動:

docker compose up -d

如果 Oracle Cloud VM 有啟用 iptables / firewalld,記得開放 TCP 3000 埠。另外,OCI Console 嘅 Security List 都要加入相應 ingress rule,先可以喺瀏覽器直接存取 http://你的VMIP:3000

Configuration

  • TZ=Asia/Hong_Kong:容器日誌同排程使用香港時區。
  • NO_SETUP=true:跳過首次網頁設定,直接以環境變數運行。
  • GITHUB_TOKEN:用嚟整合 git,令 agent 可以讀取 repo、開 issue、建立 pull request。建議使用具備 repoworkflow scope 嘅 Personal Access Token(PAT)。
  • ENABLE_AUTOMATIONS=false:呢個係 1.11.0 重要 workaround。前端 default 啟用 Automations,但後端未有對應 Automations API,令到 /automations 頁面 crash。因此要關閉。
  • AGENT_SERVER_IMAGE_REPOSITORY / AGENT_SERVER_IMAGE_TAG:指定 agent-server 映像位置同 tag。main tag 跟隨 OpenHands 最新開發版。

如果需要經統一模型 gateway 連接多個 LLM,可以使用 litellm。OpenHands 支援 OpenAI-compatible API,所以將 LLM_BASE_URL 指向 LiteLLM proxy,再由 LiteLLM 轉發去 GPT、Claude 或其他模型即可。

Operations

日常操作可以用以下指令:

docker compose logs -f openhands
docker compose restart openhands
docker compose pull openhands && docker compose up -d

如果容器啟動失敗,最常見原因包括:

  • /patches/patch_sandbox_internal_url.py 喺映像入面唔存在。
  • sed 搵唔到原本嘅 InMemoryRateLimiter(requests=10, seconds=1) 字串,表示上游代碼改咗。
  • 3000 埠被其他程序佔用。
  • GITHUB_TOKEN 未正確設定。

呢個 compose 部署冇掛載持久化 volume。因此容器重建之後,容器內嘅 session、暫存資料同未寫入外部儲存嘅內容會消失。如果實際使用需要持久保存,可以自行加入 volume,或者將 OpenHands 嘅 state 目錄掛載到宿主机。Oracle Cloud VM 嘅 boot volume 容量有限,記得留意磁碟空間。

FAQ

Q:點解要 patch rate limit?
OpenHands 嘅 sandbox 執行大量操作時,會有短時間 burst request。原本 InMemoryRateLimiter(requests=10, seconds=1) 每秒上限只有 10,好容易收到 429。改為 300 係為咗避免呢類衍生錯誤。

Q:點解要關閉 ENABLE_AUTOMATIONS
OpenHands 1.11.0 嘅前端 default 將 Automations 開啟,但後端未有提供 Automations API。前端一載入 /automations 頁面就會 crash。關閉呢個功能係最安全嘅暫時方案。

Q:OpenHands 同 LiteLLM 有乜關係?
OpenHands 需要 LLM 做 agent 推理。用 litellm 可以將多個模型供應商統一成一個 OpenAI-compatible endpoint,然後畀 OpenHands 連接。咁樣就可以集中控制 API key、成本同模型路由。

Q:點解用 main tag 而唔用 release tag?
因為呢個部署希望跟隨最新功能。main tag 對應 OpenHands 主分支最新 build,但同時意味住可能有 upstream bug。如果追求穩定,可以改用正式 release tag,但要重新檢查 ENABLE_AUTOMATIONS 等兼容設定。

Source

Coverage auto (container scan)