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:
tomasz-syn-grzegorza
2026-07-05 12:02:04 +00:00
commit 359afb3a59
153 changed files with 18169 additions and 0 deletions
+154
View File
@@ -0,0 +1,154 @@
# GPU Fan Control stack
Sterowanie wentylatorami **RTX 3090 Ti** na headless Ubuntu przez NVML — bez `nvidia-settings` i bez GUI.
**Panel webowy** jest w **Server UI** (`http://<host>:8091` → zakładka **GPU Fan**). Ten stack uruchamia tylko **agenta API** na localhost.
## Porty
| Serwis | Port | Dostęp |
|--------|------|--------|
| GPU Fan agent API | **18090** | `127.0.0.1` tylko (systemd, root) |
| GPU Fan UI | — | Server UI **:8091** (zakładka GPU Fan) |
Port **8090** nie jest już używany w produkcji.
## Jak to działa
```mermaid
flowchart LR
browser["Przeglądarka :8091"]
serverUI["server-ui"]
agent["fan_daemon.py :18090"]
nvml["NVML / pynvml"]
gpu["RTX 3090 Ti"]
browser --> serverUI
serverUI -->|"proxy /api/gpu-fan"| agent
agent --> nvml
nvml --> gpu
```
| Element | Opis |
|---------|------|
| Agent | `fan_daemon.py` — pętla NVML + API REST |
| Dev UI | `app.py` — monolit z UI (tylko dev / DRY_RUN) |
| Logika | `fan_controller.py` — interpolacja krzywej |
| Konfiguracja | `/etc/gpu-fan/curve.json` |
| systemd | `gpu-fan.service` (root, auto-restart) |
## Wymagania
- Sterownik NVIDIA ≥ 520 (testowane: **595-server-open**)
- Root / sudo (zapis NVML wymaga uprawnień root)
- Python 3 + venv (instalowane przez `install.sh`)
- **Server UI** na :8091 (proxy do agenta)
## Szybki start
```bash
cd stacks/gpu-fan
cp ../control-plane/.env.example ../control-plane/.env
sudo scripts/install.sh
sudo systemctl start gpu-fan
cd ../server-ui
sudo scripts/install.sh
```
Panel: `http://<IP-serwera>:8091` → zakładka **GPU Fan**.
Po zmianach w kodzie:
```bash
sudo scripts/install.sh && sudo systemctl restart gpu-fan
cd ../server-ui && sudo scripts/install.sh && sudo systemctl restart server-ui
```
Konfiguracja: produkcja `/opt/control-plane/.env`, dev `stacks/control-plane/.env`.
### Klucz API
Jeden wspólny `API_KEY` w `/opt/control-plane/.env` — auth panelu Server UI i agenta gpu-fan (proxy `/api/gpu-fan/*`).
W panelu Server UI wpisz ten sam klucz w polu **API Key** (lub `?api_key=...` w URL).
## Preset max cooling
Domyślna krzywa w [`curve.default.json`](curve.default.json):
| Temp | Speed |
|------|-------|
| 30°C | 50% |
| 40°C | 65% |
| 50°C | 80% |
| 55°C | 90% |
| 60°C | 100% |
| 70°C+ | 100% |
## Tryby
| Tryb | Opis |
|------|------|
| `curve` | Krzywa z JSON — interpolacja liniowa |
| `manual` | Stała prędkość (np. 100% awaryjnie) |
| `auto` | Oddaje sterowanie driverowi NVIDIA |
## API agenta (localhost :18090)
| Endpoint | Metoda | Opis |
|----------|--------|------|
| `/api/status` | GET | Temperatura, wentylatory, moc, tryb |
| `/api/curve` | GET/PUT | Odczyt / zapis krzywej |
| `/api/mode` | POST | `{"mode":"auto\|curve\|manual","speed":100}` |
| `/api/reload` | POST | Przeładuj `curve.json` (jak `SIGHUP`) |
Z LAN używaj proxy Server UI: `/api/gpu-fan/status`, `/api/gpu-fan/curve`, itd.
## Ograniczenia NVIDIA
- `nvidia-smi` **nie steruje** wentylatorami — tylko odczyt
- API akceptuje **0%** (= auto) lub **30100%**
- Po `systemctl stop gpu-fan` wentylatory wracają do trybu auto drivera
## Struktura
```
stacks/gpu-fan/
├── README.md
├── fan_daemon.py # produkcja — agent API
├── app.py # dev — UI + API (opcjonalnie)
├── fan_controller.py
├── curve.default.json
├── requirements.txt
├── gpu-fan.service
├── .env.example
├── static/index.html # referencja UI (wbudowane w server-ui)
└── scripts/
├── install.sh
├── enable-lan.sh # konfiguruje agent + wskazówka :8091
└── status.sh
```
## Troubleshooting
**`Insufficient Permissions`** — uruchom jako root (`sudo systemctl start gpu-fan`).
**Panel GPU Fan pusty / 502** — sprawdź agent: `curl -s http://127.0.0.1:18090/api/status -H "X-API-Key: ..."`
**Port 18090 zajęty**`scripts/status.sh` / `sudo scripts/status.sh --cleanup`
**Przeładuj krzywą bez restartu:**
```bash
sudo systemctl reload gpu-fan
```
## Dokumentacja
| Dokument | Opis |
|----------|------|
| [docs/00-START-TUTAJ.md](docs/00-START-TUTAJ.md) | Mapa — zacznij tutaj |
| [docs/02-OTWIERANIE-UI-W-PRZEGLADARCE.md](docs/02-OTWIERANIE-UI-W-PRZEGLADARCE.md) | Panel w Server UI :8091 |
| [docs/05-DLACZEGO-NIE-DOCKER.md](docs/05-DLACZEGO-NIE-DOCKER.md) | Dlaczego host, nie Docker |