Files
ubuntu-bare-metal/coding-agent/SERVER-UI-PORT-CONFIG.md
T
tomasz-syn-grzegorza 359afb3a59 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>
2026-07-05 12:02:04 +00:00

174 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Server UI — edycja portów stacków
**Data:** 2026-07-05
**Host:** gmktec-k11
**Kontekst:** Linki „Otwórz :PORT” w Server UI brały port z `stacks.yaml`, podczas gdy Docker mapował port z osobnego `stacks/<name>/.env`. Wdrożono jeden source of truth w `.env` stacku + edycję w UI.
**Powiązane:**
- [`stacks/server-ui/`](../stacks/server-ui/)
- [`coding-agent/SERVER-UI-ARCHITECTURE-RESEARCH.md`](SERVER-UI-ARCHITECTURE-RESEARCH.md)
- [`coding-agent/CONVENTIONS.md`](CONVENTIONS.md)
---
## 1. Executive summary
Server UI odczytuje i zapisuje port hosta w pliku `stacks/<name>/.env` (np. `LOCALAI_PORT=8070`). Karty stacków mają pole numeryczne i przycisk **Zapisz port**; po zapisie uruchamiany jest `docker compose up -d --force-recreate` gdy stack działa. Nowa usługa wymaga tylko wpisu w `stacks.yaml` z polami `port_env`, `port_default`, `port_editable`.
---
## 2. As-is / to-be
| Aspekt | Przed | Po |
|--------|-------|-----|
| Źródło portu w linku UI | `stacks.yaml``ui_port` (statyczny) | `stacks/<name>/.env``port_env` |
| Edycja portu | ręcznie w `.env` + restart compose | UI + `PATCH /api/stacks/{id}/port` |
| Nowa usługa | hardcode w JS | metadane w `stacks.yaml` |
| NPMPlus | link :81 | read-only (host network) |
```mermaid
flowchart LR
yaml[stacks.yaml port_env metadata]
env[stack .env]
api[Server UI API]
ui[Stack card port input]
compose[docker compose force-recreate]
yaml --> api
env --> api
api --> ui
api -->|PATCH| env
env --> compose
```
---
## 3. Konfiguracja stacków (`stacks.yaml`)
| Stack | `port_env` | `port_default` | `port_editable` |
|-------|------------|----------------|-----------------|
| localai | `LOCALAI_PORT` | 8080 | true |
| comfyui | `COMFYUI_PORT` | 8188 | true |
| vllm | `VLLM_PORT` | 8000 | true |
| npmplus | — | 81 | false |
**Nowa usługa** — dodaj wpis:
```yaml
- id: myservice
name: My Service
compose_dir: myservice
profile: myservice
container: myservice
ui_port: 9000 # fallback gdy brak w .env
port_env: MYSERVICE_PORT
port_default: 9000
port_editable: true
gpu: false
```
W `docker-compose.yml` stacku: `"${MYSERVICE_PORT:-9000}:9000"`.
---
## 4. API
### `GET /api/stacks`
Każdy stack zawiera dodatkowo:
```json
{
"ui_port": 8070,
"port_env": "LOCALAI_PORT",
"port_editable": true,
"port_default": 8080,
"published_port": 8070,
"port_pending_restart": false
}
```
`port_pending_restart`: kontener działa, ale opublikowany port ≠ wartość w `.env`.
### `PATCH /api/stacks/{stack_id}/port`
**Auth:** `X-API-Key` (jak start/stop)
**Body:**
```json
{ "port": 8070, "recreate": true }
```
**Odpowiedź:**
```json
{
"ok": true,
"stack_id": "localai",
"port": 8070,
"port_env": "LOCALAI_PORT",
"requires_restart": false,
"recreated": true,
"running": true
}
```
**Błędy:**
- `400` — stack bez edycji portu (npmplus)
- `409` — port zajęty / poza zakresem 102465535
- `500` — błąd docker compose
**Zarezerwowane porty:** 80, 443, 8090 (gpu-fan), 18090 (gpu-fan agent), `SERVER_UI_PORT` (8091).
---
## 5. Pliki zmienione
| Plik | Zmiana |
|------|--------|
| `stacks/server-ui/stacks.yaml` | `port_env`, `port_default`, `port_editable` |
| `stacks/server-ui/compose_runner.py` | read/write `.env`, walidacja, recreate |
| `stacks/server-ui/app.py` | `PATCH /api/stacks/{id}/port` |
| `stacks/server-ui/static/index.html` | input portu w kartach stacków |
---
## 6. Weryfikacja
```bash
cd ~/cursor/ubuntu-bare-metal/stacks/server-ui
# Lista stacków z portami
curl -s http://127.0.0.1:8091/api/stacks | python3 -m json.tool
# Zmiana portu (wymaga API_KEY z .env)
curl -s -X PATCH http://127.0.0.1:8091/api/stacks/localai/port \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"port":8070,"recreate":true}'
grep LOCALAI_PORT ../localai/.env
```
**UI:** zakładka Stacki → karta LocalAI → pole portu → **Zapisz port** → link „Otwórz” się aktualizuje.
**Prod:** `sudo scripts/install.sh && sudo systemctl restart server-ui`
---
## 7. Uwagi operacyjne
- Po zmianie `LOCALAI_PORT` zaktualizuj **upstream w NPMPlus** ręcznie (proxy host → nowy port).
- `docker compose restart` **nie** zmienia mapowania portów — wymagany recreate (`recreate: true` w API).
- NPMPlus (`network_mode: host`) — port 81 tylko do odczytu w UI.
---
## 8. Checklist wdrożenia
- [x] Metadane portów w `stacks.yaml`
- [x] Backend: odczyt/zapis `.env`, walidacja, recreate
- [x] API `PATCH /port`
- [x] UI: input + Zapisz w kartach
- [x] NPMPlus read-only
- [ ] `install.sh` + restart server-ui na produkcji
- [ ] Test zmiany portu LocalAI na hoście