diff --git a/docs/features/open-terminal/advanced/terminals/docker-backend.md b/docs/features/open-terminal/advanced/terminals/docker-backend.md index 296ee4375..d62af6d54 100644 --- a/docs/features/open-terminal/advanced/terminals/docker-backend.md +++ b/docs/features/open-terminal/advanced/terminals/docker-backend.md @@ -7,6 +7,8 @@ title: "Docker Backend" Terminals with the Docker backend runs on a single Docker host and provisions an isolated [Open Terminal](/features/open-terminal) container for every user. Each person gets their own filesystem, processes, and resource limits — without needing Kubernetes. +For an overview of how Terminals works and how it compares to the built-in multi-user mode, see the [Terminals overview](./). + ```mermaid flowchart LR OW["Open WebUI"] @@ -30,23 +32,9 @@ flowchart LR --- -## How it works - -1. A user opens a terminal in Open WebUI. -2. Open WebUI proxies the request to the **Terminals orchestrator**. -3. The orchestrator checks if the user already has a running container. - - If not, it pulls the Open Terminal image and creates a new container for that user. - - If the container exists but is stopped, it starts it back up. -4. Once the container is healthy (responds to `/health`), the orchestrator proxies all traffic to it. -5. A background cleanup loop tears down containers that have been idle longer than the configured timeout. - -On restart, the orchestrator **reconciles** — it rediscovers existing containers by label so no work is lost. - ---- - ## Prerequisites -- Docker Engine installed +- [Docker Engine](https://docs.docker.com/engine/install/) installed and running - Open WebUI running (or ready to deploy alongside) - [Open WebUI Enterprise License](https://openwebui.com/enterprise) @@ -63,9 +51,29 @@ services: ports: - "3000:8080" environment: - # Point Open WebUI at the orchestrator. - # This is auto-detected as an orchestrator connection. - - 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"}]}}] + # Connect Open WebUI to the Terminals orchestrator. + # The JSON array defines one terminal connection: + # id/name — identifier shown in the UI + # url/key — orchestrator address and shared API key + # auth_type — "bearer" sends the key as a Bearer token + # access_grants — who can use this connection + # principal_type: "user", principal_id: "*" → all users + - >- + 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: @@ -99,7 +107,9 @@ networks: ``` :::warning Docker socket access -The orchestrator mounts the Docker socket so it can create and manage containers. This grants broad control over the Docker daemon. In production, consider using a Docker socket proxy like [Tecnativa/docker-socket-proxy](https://github.com/Tecnativa/docker-socket-proxy) to restrict which API calls are allowed. +The Docker socket (`/var/run/docker.sock`) is the API endpoint that programs use to create, start, and stop containers on the host. Mounting it into the orchestrator gives it full control over the Docker daemon — meaning it could, in theory, access any container on the host. + +For production deployments, use a Docker socket proxy like [Tecnativa/docker-socket-proxy](https://github.com/Tecnativa/docker-socket-proxy) to restrict the orchestrator to only the API calls it needs (container create, start, stop, remove, inspect). ::: Set the shared API key in a `.env` file next to your Compose file: @@ -163,13 +173,7 @@ All orchestrator settings are configured via environment variables prefixed with ## Policies -The orchestrator supports **policies** — named environment configurations that let you offer different setups to different teams. For example, a `data-science` policy might use a larger image with pre-installed Python packages, while a `development` policy uses the default slim image. - -Policies are managed via the orchestrator's REST API (`/api/v1/policies`). Each policy is then referenced by a terminal connection in Open WebUI under **Settings → Connections**. - -When a policy is configured, requests are routed through `/p/{policy_id}/` — for example, `/p/data-science/execute`. - -👉 **[See the Policies guide for full details →](./policies.md)** +The orchestrator supports **policies** — named environment configurations that let you offer different setups to different teams. See the [Policies guide](./policies) for full details on creating and managing policies. --- @@ -202,16 +206,3 @@ If a container with the same name already exists (e.g., from a previous failed c - **Single host** — all user containers run on one Docker host. For high availability or larger teams, use the [Kubernetes Operator](./kubernetes-operator). - **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. - ---- - -## Next steps - -- [Kubernetes Operator](./kubernetes-operator) — production-grade deployment with CRD-based lifecycle management -- [Multi-User Setup](../multi-user) — comparison of isolation approaches -- [Security best practices](../security) -- [Configuration reference](../configuration) — all Open Terminal container settings - -:::info Enterprise license required -Terminals requires an [Open WebUI Enterprise License](https://openwebui.com/enterprise). See the [Terminals repository](https://github.com/open-webui/terminals) for license details. -::: diff --git a/docs/features/open-terminal/advanced/terminals/index.md b/docs/features/open-terminal/advanced/terminals/index.md index 3891a3ce6..d73b82060 100644 --- a/docs/features/open-terminal/advanced/terminals/index.md +++ b/docs/features/open-terminal/advanced/terminals/index.md @@ -7,6 +7,12 @@ title: "Overview" **Terminals** is an enterprise orchestration layer for [Open Terminal](/features/open-terminal) that provisions a fully isolated terminal container for every user. Instead of sharing a single container, each person gets their own — with separate files, processes, resource limits, and network isolation. +:::tip Quick navigation +- **Just want to try it?** → [Docker Compose quickstart](./docker-backend) +- **Running Kubernetes?** → [Helm chart deployment](./kubernetes-operator) +- **Need different environments per team?** → [Policies guide](./policies) +::: + ```mermaid flowchart LR OW["Open WebUI"] @@ -38,6 +44,17 @@ Open Terminal's [built-in multi-user mode](../multi-user#option-1-built-in-multi | **Infrastructure** | Single container | Docker host or Kubernetes cluster | | **Best for** | Small trusted teams | Production, larger teams, untrusted users | +:::info Key concepts +If you're new to containers and orchestration, here's a quick glossary: + +- **Container** — a lightweight, isolated environment that packages an application and its dependencies. Think of it as a mini virtual machine. +- **Docker** — a tool for running containers on a single machine. +- **Kubernetes (K8s)** — a platform for running and managing containers across a cluster of machines. Used for production-scale deployments. +- **Helm chart** — a package format for Kubernetes. Similar to `docker-compose.yaml` but for Kubernetes clusters. +- **CRD (Custom Resource Definition)** — a way to extend Kubernetes with new object types. Terminals defines a `Terminal` CRD so Kubernetes can manage terminal instances natively. +- **API key** — a secret token used to authenticate requests between services. +::: + --- ## How it works @@ -45,13 +62,15 @@ Open Terminal's [built-in multi-user mode](../multi-user#option-1-built-in-multi Terminals sits between Open WebUI and the Open Terminal instances: 1. A user activates a terminal in Open WebUI. -2. Open WebUI proxies the request to the **Terminals orchestrator**. +2. Open WebUI proxies the request to the **Terminals orchestrator** — a service that manages the lifecycle of terminal containers. 3. The orchestrator provisions a personal Open Terminal container for that user (or reconnects to an existing one). 4. All traffic is proxied through the orchestrator. The user never connects to their container directly. 5. Idle containers are automatically cleaned up after a configurable timeout. Data optionally persists across sessions. The orchestrator also exposes the same OpenAPI-based tool interface as Open Terminal, so the AI can execute commands, read files, and run code — all scoped to the requesting user's container. +The [Docker Backend](./docker-backend) and [Kubernetes Operator](./kubernetes-operator) pages cover backend-specific details of how provisioning works in each environment. + --- ## Policies @@ -88,7 +107,7 @@ Includes a ready-to-use Docker Compose file. **[Get started →](./docker-backen ### [Kubernetes Operator](./kubernetes-operator) -Production-grade deployment using a CRD-based Kopf operator. Deploys alongside Open WebUI via the Helm chart. Best for: +Production-grade deployment using a Kubernetes operator. Deploys alongside Open WebUI via the Helm chart. Best for: - Production environments - Larger teams requiring scalability @@ -102,16 +121,49 @@ Integrates as a subchart of the Open WebUI Helm chart — enable with `terminals The orchestrator supports three authentication modes: -| Mode | When to use | -| :--- | :--- | -| **Open WebUI JWT** | Production. Set `TERMINALS_OPEN_WEBUI_URL` and the orchestrator validates tokens against your Open WebUI instance. | -| **Shared API key** | Standard. Set `TERMINALS_API_KEY` to a shared secret that Open WebUI includes in requests. | -| **Open** | Development only. No auth — do not use in production. | +| Mode | When to use | How to configure | +| :--- | :--- | :--- | +| **Open WebUI JWT** | Production. The orchestrator validates tokens against your Open WebUI instance. | Set `TERMINALS_OPEN_WEBUI_URL` on the orchestrator to your Open WebUI URL. | +| **Shared API key** | Standard. Open WebUI includes a shared secret in every request. | Set `TERMINALS_API_KEY` to the same value on both Open WebUI and the orchestrator. | +| **Open** | Development only. No auth — 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 container creation. Look for errors related to image availability 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. + +### Container 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, containers 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 + +- [Multi-User Setup](../multi-user) — comparison of isolation approaches +- [Security best practices](../security) +- [Configuration reference](../configuration) — all Open Terminal container settings + +--- + ## License Terminals requires an [Open WebUI Enterprise License](https://openwebui.com/enterprise). See the [Terminals repository](https://github.com/open-webui/terminals) for details. diff --git a/docs/features/open-terminal/advanced/terminals/kubernetes-operator.md b/docs/features/open-terminal/advanced/terminals/kubernetes-operator.md index 1f1d4ee5e..577349a6b 100644 --- a/docs/features/open-terminal/advanced/terminals/kubernetes-operator.md +++ b/docs/features/open-terminal/advanced/terminals/kubernetes-operator.md @@ -7,6 +7,8 @@ title: "Kubernetes Operator" Terminals with the Kubernetes Operator backend is the production-grade deployment for multi-tenant terminals on Kubernetes. A [Kopf](https://kopf.readthedocs.io/)-based operator watches `Terminal` custom resources and manages the full lifecycle of per-user Pods, Services, PVCs, and Secrets. +For an overview of how Terminals works and how it compares to the built-in multi-user mode, see the [Terminals overview](./). + ```mermaid flowchart LR OW["Open WebUI"] @@ -41,10 +43,10 @@ The Kubernetes deployment includes three components: | Component | Role | | :--- | :--- | | **Orchestrator** | FastAPI service that receives requests from Open WebUI, creates `Terminal` custom resources, and proxies traffic to user Pods once they're running. | -| **Operator** | Kopf controller that watches `Terminal` CRs and reconciles the underlying infrastructure — creates Pods, Services, Secrets, and PVCs for each terminal. | -| **Terminal CRD** | A `Terminal` custom resource (`terminals.openwebui.com/v1alpha1`) that declaratively represents a user's terminal instance. | +| **Operator** | [Kopf](https://kopf.readthedocs.io/) controller that watches `Terminal` CRs and reconciles the underlying infrastructure — creates Pods, Services, Secrets, and PVCs for each terminal. (Kopf is a Python framework for building Kubernetes operators.) | +| **Terminal CRD** | A `Terminal` custom resource definition (`terminals.openwebui.com/v1alpha1`) that declares a new Kubernetes object type representing a user's terminal instance. | -When a user opens a terminal in Open WebUI: +The provisioning flow works as follows: 1. Open WebUI proxies the request to the **orchestrator**. 2. The orchestrator creates a `Terminal` CR in the cluster. @@ -56,6 +58,15 @@ When a user opens a terminal in Open WebUI: --- +## Prerequisites + +- A running Kubernetes cluster (v1.24+) +- [Helm](https://helm.sh/docs/intro/install/) v3 installed +- `kubectl` configured to access your cluster +- [Open WebUI Enterprise License](https://openwebui.com/enterprise) + +--- + ## Deployment with Helm The recommended deployment method is through the **Open WebUI Helm chart**, which includes Terminals as an optional subchart. @@ -248,7 +259,8 @@ kubectl get terminals -n open-webui # Inspect a specific terminal kubectl describe terminal terminal-a1b2c3-default -n open-webui -# Delete a terminal (Pod, Service, and Secret are garbage-collected via ownerReferences) +# Delete a terminal (Pod, Service, and Secret are garbage-collected via ownerReferences — +# Kubernetes automatically deletes child resources when the parent is removed) kubectl delete terminal terminal-a1b2c3-default -n open-webui ``` @@ -297,7 +309,7 @@ All configurable values under the `terminals` key: ## RBAC requirements -If you're not using the Helm chart, the operator's ServiceAccount needs a ClusterRole with these permissions: +RBAC (Role-Based Access Control) defines what Kubernetes permissions the operator needs. If you're not using the Helm chart (which configures RBAC automatically), the operator's ServiceAccount needs a ClusterRole with these permissions: | Resource | Verbs | | :--- | :--- | @@ -334,16 +346,3 @@ kubectl logs -n open-webui deployment/-terminals-operator --tail=50 ```bash kubectl logs -n open-webui deployment/-terminals-orchestrator --tail=50 ``` - ---- - -## Next steps - -- [Docker Backend](./docker-backend) — simpler single-host deployment without Kubernetes -- [Multi-User Setup](../multi-user) — comparison of isolation approaches -- [Security best practices](../security) -- [Configuration reference](../configuration) — all Open Terminal container settings - -:::info Enterprise license required -Terminals requires an [Open WebUI Enterprise License](https://openwebui.com/enterprise). See the [Terminals repository](https://github.com/open-webui/terminals) for license details. -::: diff --git a/docs/features/open-terminal/advanced/terminals/policies.md b/docs/features/open-terminal/advanced/terminals/policies.md index 6d85eaeed..63e95ff60 100644 --- a/docs/features/open-terminal/advanced/terminals/policies.md +++ b/docs/features/open-terminal/advanced/terminals/policies.md @@ -52,7 +52,9 @@ The `storage_mode` field controls how persistent volumes are allocated on Kubern | :--- | :--- | :--- | | `per-user` | Each user gets their own PVC. Full isolation. | ReadWriteOnce | | `shared` | A single PVC is shared by all users, with each user's data in a `subPath` under their user ID. Requires a storage class that supports ReadWriteMany (e.g., NFS, EFS). | ReadWriteMany | -| `shared-rwo` | A single ReadWriteOnce PVC is shared. All terminal pods are scheduled to the same node via pod affinity. Useful when RWX storage is unavailable. | ReadWriteOnce | +| `shared-rwo` | A single ReadWriteOnce PVC is shared. All terminal pods are scheduled to the same node via pod affinity (Kubernetes ensures they all land on the machine that has the volume mounted). Useful when ReadWriteMany storage is unavailable. | ReadWriteOnce | + +**ReadWriteOnce (RWO)** means the volume can only be mounted by pods on a single node at a time. **ReadWriteMany (RWX)** means multiple nodes can mount and write to the volume simultaneously. ### Environment variables @@ -72,6 +74,10 @@ Environment variables in a policy are visible to the terminal user (they can run Policies are managed via the orchestrator's REST API. All endpoints require authentication with the orchestrator's API key. +:::tip New to REST APIs? +The examples below use `curl`, a command-line tool for making HTTP requests. You can also use graphical tools like [Postman](https://www.postman.com/) or [HTTPie Desktop](https://httpie.io/) if you prefer. The key concepts: `PUT` creates or updates a resource, `GET` retrieves it, and `DELETE` removes it. +::: + ### Create a policy ```bash