跳到主要内容

Terminals (Orchestrator)

Terminals 是用于 Open Terminal 的企业级编排层,它为每个用户分配一个完全隔离的终端容器。每个用户不再共享同一个容器,而是获得自己专属的容器,配备独立的文件、进程、资源限制以及网络隔离。

快速导航

工作原理

编排器(orchestrator)介于 Open WebUI 和 Open Terminal 实例之间:

  1. 用户在 Open WebUI 中激活终端。
  2. Open WebUI 将请求代理给编排器,这是一个用于管理终端容器生命周期的服务。
  3. 编排器为该用户配置一个专属的 Open Terminal 容器(或重新连接到已有的容器)。
  4. 所有流量都通过编排器进行代理。用户永远不会直接连接到他们的容器。
  5. 空闲容器在达到可配置的超时时间后会被自动清理。可以选择跨会话持久化数据。

编排器还暴露了与 Open Terminal 相同的基于 OpenAPI 的工具接口,因此 AI 可以执行命令、读取文件和运行代码,所有操作都被限制在请求用户的容器范围内。


部署

前置条件

使用 Docker Compose 快速开始

本 Compose 文件将 Open WebUI 和 Terminals 编排器部署在一起。

services:
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    ports:
      - "3000:8080"
    environment:
      - >-
        TERMINAL_SERVER_CONNECTIONS=[{
          "id": "terminals",
          "name": "Terminals",
          "enabled": true,
          "url": "http://terminals:3000",
          "key": "${TERMINALS_API_KEY}",
          "auth_type": "bearer",
          "config": {
            "access_grants": [{
              "principal_type": "user",
              "principal_id": "*",
              "permission": "read"
            }]
          }
        }]
    volumes:
      - open-webui:/app/backend/data
    networks:
      - webui
    depends_on:
      - terminals

  terminals:
    image: ghcr.io/open-webui/terminals:latest
    environment:
      - TERMINALS_BACKEND=docker
      - TERMINALS_API_KEY=${TERMINALS_API_KEY}
      - TERMINALS_IMAGE=ghcr.io/open-webui/open-terminal:latest
      - TERMINALS_NETWORK=open-webui-network
      - TERMINALS_IDLE_TIMEOUT_MINUTES=30
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - terminals-data:/app/data
    networks:
      - webui

volumes:
  open-webui:
  terminals-data:

networks:
  webui:
    name: open-webui-network

在您的 Compose 文件旁边的 .env 文件中设置共享 API 密钥:

TERMINALS_API_KEY=change-me-to-a-strong-random-value

然后启动所有服务:

docker compose up -d

Open WebUI 将可在 http://localhost:3000 访问。当任何用户激活终端时,编排器将自动配置其专属的容器。

Docker 套接字(socket)访问

编排器需要访问 Docker 套接字(/var/run/docker.sock)来管理容器。在生产环境中,建议使用诸如 Tecnativa/docker-socket-proxy 之类的 Docker 套接字代理,以限制其能够发起的 API 调用。


配置参考
变量默认值描述
TERMINALS_BACKENDdocker后端类型。在此部署模式下设置为 docker
TERMINALS_API_KEY(空)用于对来自 Open WebUI 的请求进行身份验证的共享密钥。必需。
TERMINALS_IMAGEghcr.io/open-webui/open-terminal:latest用户终端的默认容器镜像。
TERMINALS_PORT3000编排器监听的端口。
TERMINALS_HOST0.0.0.0编排器绑定的地址。
TERMINALS_NETWORK(空)用户容器的 Docker 网络。设置后,容器之间可以通过服务名称进行通信。
TERMINALS_DOCKER_HOST127.0.0.1已发布容器端口的地址。仅在未设置 TERMINALS_NETWORK 时有用。
TERMINALS_DATA_DIRdata/terminals存放每个用户工作区数据的宿主机目录。
TERMINALS_IDLE_TIMEOUT_MINUTES0 (已禁用)容器被停止前的无活动空闲时间(分钟)。通常设置为 30
TERMINALS_MAX_CPU(空)用户容器的 CPU 限制(例如,2)。
TERMINALS_MAX_MEMORY(空)用户容器的内存限制(例如,4Gi)。
TERMINALS_OPEN_WEBUI_URL(空)如果设置,则对该 Open WebUI 实例验证传入的 JWT,而不是使用 TERMINALS_API_KEY

容器生命周期详情

命名。 容器被命名为 terminals-{policy_id}-{user_id},从而极易通过 docker ps --filter "label=managed-by=terminals" 来进行过滤筛选。

健康检查。 创建容器后,编排器会轮询轮查其 /health 端点,直到返回 HTTP 200(最多等待 15 秒)。只有在通过后,它才开始代理流量。

状态协调(Reconciliation)。 如果编排器重启,它会通过标签重新发现已存在且正在运行的容器,并从容器配置中恢复其 API 密钥。这可以防止创建重复的容器。

冲突处理。 如果已存在具有相同名称的容器(例如,由于之前清理失败),编排器会强制移除旧容器并尝试重新创建,最多重试 3 次。


局限性

  • 单主机。所有用户容器运行在单个 Docker 主机上。对于高可用性需求或更大型的团队,请使用 Kubernetes Operator 后端。
  • 无内置高可用(HA)。如果编排器宕机,处于活动状态的终端会话会被中断(但容器会保持运行,且在编排器重启后会被状态协调恢复)。
  • 需要 Docker 套接字。编排器需要访问 Docker 套接字来管理容器。

身份验证

编排器支持三种身份验证模式:

模式适用场景如何配置
Open WebUI JWT生产环境。编排器会根据您的 Open WebUI 实例验证令牌。在编排器上将 TERMINALS_OPEN_WEBUI_URL 设置为您的 Open WebUI URL。
共享 API 密钥标准配置。Open WebUI 在每次请求中都包含一个共享的密钥(secret)。在 Open WebUI 和编排器上将 TERMINALS_API_KEY 设置为相同的值。
公开 (Open)仅用于开发阶段。无身份验证。请勿在生产环境中使用。保持 TERMINALS_OPEN_WEBUI_URLTERMINALS_API_KEY 未设置。

当通过 Docker Compose 或 Helm 部署时,Open WebUI 和编排器之间的共享 API 密钥会自动配置完成。


问题排查

终端无法启动

  1. 检查编排器日志。 编排器会记录完整的分配流程,包括镜像拉取和容器创建。查找与镜像可用性或资源限制相关的错误。
  2. 验证 API 密钥。 确保 Open WebUI 和编排器之间的 TERMINALS_API_KEY 匹配。如果不匹配,会导致静默授权失败。
  3. 检查镜像拉取权限。 如果使用私有容器镜像仓库,请确保编排器(Docker)或集群(Kubernetes)已配置拉取凭据。

身份验证失败

  • 如果使用 JWT 模式,确认 TERMINALS_OPEN_WEBUI_URL 指向可达的 Open WebUI 实例。
  • 如果使用 API 密钥模式,确认两端的密钥设置完全一致。检查是否有额外的空格或换行符。
  • 检查编排器日志中的 401403 响应。

容器回收过快

增加 TERMINALS_IDLE_TIMEOUT_MINUTES(或策略中的 idle_timeout_minutes)。默认值为 0(禁用),但如果设置得太低,容器可能会在用户仍在工作时就被清理掉。通常推荐设置为 30

连接被拒绝

  • Docker 部署:确保设置了 TERMINALS_NETWORK,以便容器可以通过名称进行通信。如果不设置它,容器将使用发布的端口,且 TERMINALS_DOCKER_HOST 地址必须是可达的。
  • Kubernetes 部署:验证 Open WebUI Pod 是否能够访问编排器 Service。运行 kubectl get svc -n open-webui 以确认 Service 是否存在。

延伸阅读


许可证

在生产环境中使用 Terminals 需要拥有 Open WebUI 企业版许可证。详情请参阅 Terminals 仓库

This content is for informational purposes only and does not constitute a warranty, guarantee, or contractual commitment. Open WebUI is provided "as is." See your license for applicable terms.