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>
4.3 KiB
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
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
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:
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:
| 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-sminie steruje wentylatorami — tylko odczyt- API akceptuje 0% (= auto) lub 30–100%
- Po
systemctl stop gpu-fanwentylatory 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:
sudo systemctl reload gpu-fan
Dokumentacja
| Dokument | Opis |
|---|---|
| docs/00-START-TUTAJ.md | Mapa — zacznij tutaj |
| docs/02-OTWIERANIE-UI-W-PRZEGLADARCE.md | Panel w Server UI :8091 |
| docs/05-DLACZEGO-NIE-DOCKER.md | Dlaczego host, nie Docker |