Files
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

155 lines
4.3 KiB
Markdown
Raw Permalink 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.
# 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 |