Alpha – APIs and configuration may change.
Multi-tenant terminal orchestrator for Open Terminal. Provisions isolated terminal instances per user with automatic lifecycle management.
pip install -e .
terminals serveThe server starts on http://0.0.0.0:3000. An API key is auto-generated and printed to the console.
docker build -t terminals .
docker run -p 3000:3000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(pwd)/data:/app/data \
terminalsuv sync
./dev.sh # uvicorn with --reloadFrontend (admin dashboard):
cd terminals/frontend
npm install && npm run devAll Open Terminal endpoints are available under /terminals/. Include X-User-Id to identify the user.
export API_KEY="<api-key>"
export HEADERS=(-H "Authorization: Bearer $API_KEY" -H "X-User-Id: user-123")
curl -X POST http://localhost:3000/terminals/execute \
"${HEADERS[@]}" -H "Content-Type: application/json" \
-d '{"command": "echo hello"}'
curl http://localhost:3000/terminals/files/list "${HEADERS[@]}"
curl "http://localhost:3000/terminals/files/read?path=README.md" "${HEADERS[@]}"Interactive terminal sessions connect via WebSocket at /terminals/api/terminals/{session_id}. Admins can manage tenants via /api/v1/tenants/.
Settings are loaded from environment variables prefixed with TERMINALS_ (or a .env file).
| Variable | Default | Description |
|---|---|---|
TERMINALS_BACKEND |
docker |
docker, kubernetes, kubernetes-operator, local, static |
TERMINALS_API_KEY |
(auto-generated) | Bearer token for API auth |
TERMINALS_OPEN_WEBUI_URL |
Open WebUI URL for JWT auth | |
TERMINALS_DATABASE_URL |
sqlite+aiosqlite:///./data/terminals.db |
SQLAlchemy async URL |
TERMINALS_IMAGE |
ghcr.io/open-webui/open-terminal:latest |
Docker/K8s container image |
TERMINALS_IDLE_TIMEOUT_SECONDS |
1800 |
Stop idle instances (0 = disabled) |
TERMINALS_PORT |
3000 |
Server port |
See config.py for the full list including Kubernetes, static backend, and encryption settings.
| Mode | Trigger | How it works |
|---|---|---|
| Open WebUI JWT | Set TERMINALS_OPEN_WEBUI_URL |
Validates tokens against Open WebUI |
| API Key | Set TERMINALS_API_KEY |
Static bearer token |
| Open | Neither set | No auth (development only) |
docker– One container per user via Docker socketkubernetes– Pod + PVC + Service per user via K8s APIkubernetes-operator– Delegates to a Kopf operator watchingTerminalCRDslocal– Spawnsopen-terminalas a subprocess (dev/testing)static– Proxies all users to a single pre-running instance
SQLite works out of the box. For PostgreSQL:
pip install asyncpg
export TERMINALS_DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/terminalsMigrations run automatically on startup. Manual management:
terminals db upgrade # run pending migrations
terminals db current # show revision
terminals db revision -m "msg" # create migration