Initial import: bare-metal stacks, Server UI, GPU fan, tutorials.
Infrastructure configs for GMKtec K11 (Docker, vLLM, LocalAI, ComfyUI, control-plane, gpu-fan agent, Server UI with CLI/file explorer/GPU fan curve). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
# Server UI — CLI (terminal PTY)
|
||||
|
||||
**Data:** 2026-07-05
|
||||
**Status:** wdrożone (bugfix FitAddon: 2026-07-05 — patrz [SERVER-UI-CLI-BUGFIX.md](SERVER-UI-CLI-BUGFIX.md))
|
||||
|
||||
Zakładka **CLI** w panelu Server UI (`:8091`) — interaktywny shell bash w przeglądarce (PTY + xterm.js).
|
||||
|
||||
## UI
|
||||
|
||||
- Zakładka **CLI** (pierwsza, przed Pliki)
|
||||
- Hash URL: `http://<host>:8091/#cli`
|
||||
- Wymaga **API Key** w toolbarze (WebSocket nie obsługuje nagłówka `X-API-Key`)
|
||||
|
||||
## Architektura
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Browser
|
||||
participant xterm as xterm_js
|
||||
participant WS as WS_api_cli_ws
|
||||
participant PTY as cli_pty_py
|
||||
participant Shell as bash
|
||||
|
||||
Browser->>xterm: klawiatura
|
||||
xterm->>WS: dane terminala
|
||||
WS->>PTY: zapis master_fd
|
||||
PTY->>Shell: stdin
|
||||
Shell->>PTY: stdout/stderr
|
||||
PTY->>WS: odczyt master_fd
|
||||
WS->>xterm: output
|
||||
```
|
||||
|
||||
## WebSocket
|
||||
|
||||
| Parametr | Wartość |
|
||||
|----------|---------|
|
||||
| Ścieżka | `/api/cli/ws` |
|
||||
| Auth | `?api_key=<API_KEY>` (query string) |
|
||||
| Protokół I/O | surowe bajty terminala (text/binary frames) |
|
||||
| Resize | JSON: `{"type":"resize","cols":120,"rows":40}` |
|
||||
|
||||
### Przykład (wscat)
|
||||
|
||||
```bash
|
||||
API_KEY=$(sudo grep ^API_KEY= /opt/control-plane/.env | cut -d= -f2)
|
||||
|
||||
# wymaga: npm i -g wscat
|
||||
wscat -c "ws://127.0.0.1:8091/api/cli/ws?api_key=${API_KEY}"
|
||||
```
|
||||
|
||||
Bez klucza na bind LAN → połączenie zamknięte z kodem `1008`.
|
||||
|
||||
## Konfiguracja
|
||||
|
||||
W [`/opt/control-plane/.env`](/opt/control-plane/.env) (opcjonalnie):
|
||||
|
||||
| Zmienna | Domyślnie | Opis |
|
||||
|---------|-----------|------|
|
||||
| `CLI_ENABLED` | `1` | `0` = WebSocket odrzucany |
|
||||
| `CLI_SHELL` | `/bin/bash` | Shell PTY (np. `/bin/bash -l`) |
|
||||
| `CLI_DEFAULT_CWD` | `$HOME` usługi | Katalog startowy |
|
||||
| `CLI_MAX_SESSIONS` | `5` | Limit równoległych sesji WS |
|
||||
|
||||
## Uprawnienia POSIX
|
||||
|
||||
Server UI działa jako **`tomasz-syn-grzegorza`** (`server-ui.service`):
|
||||
|
||||
- `docker ps`, edycja repo, `/data/apps/` — OK
|
||||
- `sudo` — interaktywnie (hasło użytkownika w terminalu)
|
||||
- root-only pliki — odmowa jak w SSH
|
||||
|
||||
## Kod
|
||||
|
||||
| Plik | Rola |
|
||||
|------|------|
|
||||
| [`stacks/server-ui/cli_pty.py`](../stacks/server-ui/cli_pty.py) | PTY + asyncio bridge |
|
||||
| [`stacks/server-ui/app.py`](../stacks/server-ui/app.py) | WebSocket `/api/cli/ws`, mount `/static` |
|
||||
| [`stacks/server-ui/static/index.html`](../stacks/server-ui/static/index.html) | Zakładka CLI |
|
||||
| [`stacks/server-ui/static/vendor/xterm/`](../stacks/server-ui/static/vendor/xterm/) | xterm.js + FitAddon (vendored; UMD: `new FitAddon.FitAddon()`) |
|
||||
|
||||
## Bezpieczeństwo
|
||||
|
||||
- Pełny shell przez LAN = **wysokie ryzyko** — wymagany `API_KEY` przy `SERVER_UI_HOST=0.0.0.0`
|
||||
- `CLI_ENABLED=0` jako kill switch
|
||||
- `CLI_MAX_SESSIONS` ogranicza liczbę równoległych bashów
|
||||
- Brak whitelisty komend (właściciel serwera)
|
||||
- Sesja kończy się przy zamknięciu zakładki / rozłączeniu WS (nowy bash przy reconnect)
|
||||
|
||||
## Deploy
|
||||
|
||||
```bash
|
||||
sudo rsync -a --exclude '.venv' --exclude '__pycache__' \
|
||||
stacks/server-ui/ /opt/server-ui/
|
||||
sudo systemctl restart server-ui
|
||||
```
|
||||
|
||||
Tutorial użytkownika: [`manual-tutorial/10-server-ui-cli.md`](../manual-tutorial/10-server-ui-cli.md)
|
||||
|
||||
## Znane problemy / bugfix
|
||||
|
||||
Pusty terminal przy działającym API Key: [`SERVER-UI-CLI-BUGFIX.md`](SERVER-UI-CLI-BUGFIX.md)
|
||||
Reference in New Issue
Block a user