Skip to main content

Terminals (Orchestrator)

Terminals is the enterprise orchestration layer for Open Terminal. It provisions a dedicated computer substrate for every Open WebUI user: separate files, processes, package environment, resource limits, network boundary, and optional persistent storage.

Open Terminal turns one Open WebUI chat into a full agent harness with a real workspace for action. Terminals turns that into managed fleet infrastructure, so every user or policy can get the right workspace without sharing state or hand-wiring containers.

Open WebUI is where the harness is configured, governed, and observed. Terminals is the workspace lifecycle layer inside that harness: it provisions, isolates, reuses, refreshes, and resets the computer substrates agents use to do real work.

Quick navigation
  • Need to operate per-user terminal environments?Orchestration

How It Works

The orchestrator sits between Open WebUI and the per-user Open Terminal workspaces:

  1. A user activates Open Terminal in Open WebUI.
  2. Open WebUI proxies the request to the orchestrator, which manages workspace lifecycle.
  3. The orchestrator resolves the selected policy: image, resources, storage, env vars, security context, and idle timeout.
  4. The orchestrator provisions or reuses a personal Open Terminal workspace for that user and policy.
  5. All traffic is proxied through the orchestrator. The user never connects to the workspace directly.
  6. Idle workspaces are cleaned up after a configurable timeout. Files can persist across sessions when storage is enabled.

The orchestrator exposes the same OpenAPI-based tool interface as Open Terminal, so the AI can work with files, run code, execute commands, start servers, and inspect results, all scoped to the requesting user's workspace.

Why It Matters

Terminals is what makes the full agent harness operable for teams. It lets admins give agents enough environment to do real work while still controlling the boundary:

NeedWhat Terminals provides
IsolationOne workspace per user and policy, with separate files and processes
GovernancePolicy-controlled images, env vars, resource limits, storage, and security context
RepeatabilityCustom images and startup packages so users get the right tools every time
LifecycleReuse, idle cleanup, refresh, and scheduled resets
ScaleDocker for a single host, Kubernetes/operator mode for larger deployments
SupportabilityAdmin UI, logs, status, policy APIs, and predictable routing

In harness-engineering terms, Terminals owns the workspace lifecycle: provision, route, persist, reap, refresh, and reset.

Admin UI (new in 0.0.4)

The orchestrator serves a built-in minimal admin UI at / for viewing terminal status, active sessions, and policies. It is on by default and toggled with TERMINALS_ENABLE_UI; set it to false for API-only deployments.


Deployment

Prerequisites

Quick start with Docker Compose

This Compose file deploys Open WebUI and the Terminals orchestrator together.

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

Set the shared API key in a .env file next to your Compose file:

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

Then start everything:

docker compose up -d

Open WebUI will be available at http://localhost:3000. When any user activates a terminal, the orchestrator provisions their personal container automatically.

Docker socket access

The orchestrator needs access to the Docker socket (/var/run/docker.sock) to manage containers. For production, use a Docker socket proxy like Tecnativa/docker-socket-proxy to restrict the API calls it can make.


Configuration reference
VariableDefaultDescription
TERMINALS_BACKENDdockerBackend type. Set to docker for this deployment mode.
TERMINALS_API_KEY(empty)Shared secret for authenticating requests from Open WebUI. Required.
TERMINALS_IMAGEghcr.io/open-webui/open-terminal:latestDefault container image for user terminals.
TERMINALS_PORT3000Port the orchestrator listens on.
TERMINALS_HOST0.0.0.0Address the orchestrator binds to.
TERMINALS_NETWORK(empty)Docker network for user containers. When set, containers communicate by name.
TERMINALS_DOCKER_HOST127.0.0.1Address for published container ports. Only relevant without TERMINALS_NETWORK.
TERMINALS_DATA_DIRdata/terminalsHost directory for per-user workspace data.
TERMINALS_IDLE_TIMEOUT_MINUTES0 (disabled)Minutes of inactivity before a container is stopped. Set to 30 for typical usage.
TERMINALS_MAX_CPU(empty)CPU limit for user containers (e.g., 2).
TERMINALS_MAX_MEMORY(empty)Memory limit for user containers (e.g., 4Gi).
TERMINALS_OPEN_WEBUI_URL(empty)If set, validates incoming JWTs against this Open WebUI instance instead of using TERMINALS_API_KEY.
TERMINALS_ENABLE_UItrueServe the built-in minimal admin UI at /. Set false for API-only deployments.
TERMINALS_LOG_LEVELINFOServer and operator log level (DEBUG, INFO, WARNING, ERROR, CRITICAL).

Container lifecycle details

Naming. Containers are named terminals-<user-hash> (where <user-hash> is the first 12 hex chars of the SHA-256 of the user ID, for a DNS-safe name), or terminals-<user-hash>-<policy> for non-default policies. They are easy to filter with docker ps --filter "label=app.kubernetes.io/managed-by=terminals".

Health checks. After creating a container, the orchestrator polls its /health endpoint until it returns HTTP 200 (up to 15 seconds). Only then does it start proxying traffic.

Reconciliation. If the orchestrator restarts, it rediscovers existing running containers by their labels and recovers their API keys from the container configuration. This prevents duplicate containers from being created.

Conflict handling. If a container with the same name already exists (e.g., from a previous failed cleanup), the orchestrator force-removes the old container and retries up to 3 times.


Limitations

  • Single host. All user containers run on one Docker host. For high availability or larger teams, use the Kubernetes Operator backend.
  • No built-in HA. If the orchestrator goes down, active terminal sessions are interrupted (though containers keep running and are reconciled on restart).
  • Docker socket required. The orchestrator needs access to the Docker socket to manage containers.

Authentication

The orchestrator supports three authentication modes:

ModeWhen to useHow to configure
Open WebUI JWTProduction. The orchestrator validates tokens against your Open WebUI instance.Set TERMINALS_OPEN_WEBUI_URL on the orchestrator to your Open WebUI URL.
Shared API keyStandard. Open WebUI includes a shared secret in every request.Set TERMINALS_API_KEY to the same value on both Open WebUI and the orchestrator.
OpenDevelopment only. No authentication. Do not use in production.Leave both TERMINALS_OPEN_WEBUI_URL and TERMINALS_API_KEY unset.

When deployed via Docker Compose or Helm, the shared API key is configured automatically between Open WebUI and the orchestrator.


Troubleshooting

Terminal won't start

  1. Check orchestrator logs. The orchestrator logs the full provisioning flow, including image pull and workspace creation. Look for errors related to image availability, policy configuration, or resource limits.
  2. Verify the API key. Ensure TERMINALS_API_KEY matches between Open WebUI and the orchestrator. A mismatch causes silent auth failures.
  3. Check image pull access. If using a private container registry, make sure the orchestrator (Docker) or cluster (Kubernetes) has pull credentials configured.

Authentication failures

  • If using JWT mode, confirm TERMINALS_OPEN_WEBUI_URL points to a reachable Open WebUI instance.
  • If using API key mode, confirm the key is set identically on both sides. Check for extra whitespace or newlines.
  • Check the orchestrator logs for 401 or 403 responses.

Workspace is reaped too quickly

Increase TERMINALS_IDLE_TIMEOUT_MINUTES (or idle_timeout_minutes in a policy). The default is 0 (disabled), but if set too low, workspaces may be cleaned up while users are still working. A value of 30 is typical.

Connection refused

  • Docker: ensure TERMINALS_NETWORK is set so containers can communicate by name. Without it, containers use published ports and the TERMINALS_DOCKER_HOST address must be reachable.
  • Kubernetes: verify the orchestrator Service is accessible from the Open WebUI Pod. Run kubectl get svc -n open-webui to confirm the service exists.

Further reading


License

Terminals requires an Open WebUI Enterprise License for production use. See the Terminals repository for details.

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.