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.8 KiB
Control plane — jeden plik .env
Data: 2026-07-05
Status: wdrożone
gpu-fan (agent NVML) i Server UI (panel stacków) używają jednego pliku credentials.
Kanoniczne ścieżki
| Środowisko | Plik |
|---|---|
| Produkcja (systemd) | /opt/control-plane/.env |
| Dev w repo | stacks/control-plane/.env |
| Szablon | stacks/control-plane/.env.example |
Oba serwisy systemd:
EnvironmentFile=-/opt/control-plane/.env
server-ui.servicegpu-fan.service
Zmienne
| Zmienna | Opis |
|---|---|
API_KEY |
Wspólny klucz: auth panelu Server UI (X-API-Key) + auth agenta gpu-fan (proxy /api/gpu-fan/*) |
SERVER_UI_HOST, SERVER_UI_PORT |
Bind Server UI (domyślnie 0.0.0.0:8091) |
REPO_ROOT |
Ścieżka do ubuntu-bare-metal (wymagane dla Docker Server UI) |
DOCKER_GID |
GID grupy docker (Docker install) |
GPU_FAN_AGENT_URL |
URL agenta z perspektywy Server UI (http://127.0.0.1:18090 native, http://host.docker.internal:18090 Docker) |
GPU_FAN_API_HOST, GPU_FAN_API_PORT |
Bind agenta gpu-fan (domyślnie 127.0.0.1:18090) |
CURVE_PATH, POLL_INTERVAL, GPU_INDEX |
Konfiguracja NVML / krzywej wentylatorów |
Usunięte: GPU_FAN_AGENT_KEY — duplikat API_KEY.
Ładowanie w Pythonie
stacks/control-plane/env_loader.py — load_control_plane_env(stack_dir):
Produkcja (stack_dir pod /opt/): tylko /opt/control-plane/.env + os.environ (systemd).
Dev (repo stacks/*): tylko stacks/control-plane/.env + os.environ.
Nie ładowane: stacks/server-ui/.env, /opt/server-ui/.env (legacy — API_KEY usuwany przez setup-control-plane-env.sh).
Kolejność priorytetu: pliki env → os.environ wygrywa (systemd EnvironmentFile).
api_key_source(stack_dir, values) — log przy starcie Server UI (bez ujawniania sekretu).
Produkcja: env_loader.py kopiowany do /opt/control-plane/env_loader.py przez setup-control-plane-env.sh.
Instalacja / migracja
sudo bash stacks/server-ui/scripts/setup-control-plane-env.sh
sudo systemctl daemon-reload
sudo systemctl restart gpu-fan server-ui
Skrypt:
- tworzy
/opt/control-plane/.envz example jeśli brak - migruje z
/opt/server-ui/.envi/opt/gpu-fan/.env(backup.env.bak.<timestamp>) - generuje
API_KEYjeśli brak lubchange-me - sync
stacks/control-plane/.envz produkcją (ten samAPI_KEY) - usuwa
API_KEY/GPU_FAN_AGENT_KEYz legacystacks/server-ui/.env - wypisuje gotowy URL z kluczem (
print-api-key-instructions.sh)
Instrukcja dla użytkownika po instalacji:
bash stacks/server-ui/scripts/show-api-key.sh
Pełna instalacja:
sudo bash stacks/server-ui/scripts/install-control-plane.sh
Weryfikacja
bash stacks/server-ui/scripts/show-api-key.sh
API_KEY=$(sudo grep ^API_KEY= /opt/control-plane/.env | cut -d= -f2)
# Test klucza w panelu
curl -s -X POST http://127.0.0.1:8091/api/auth/verify \
-H "Content-Type: application/json" \
-d "{\"api_key\":\"${API_KEY}\"}"
# Agent bezpośrednio
curl -s http://127.0.0.1:18090/api/status -H "X-API-Key: ${API_KEY}"
# Proxy przez Server UI
curl -s http://127.0.0.1:8091/api/gpu-fan/health -H "X-API-Key: ${API_KEY}"
Oczekiwane: JSON z danymi / "ok": true.
Docker Server UI
stacks/server-ui/docker-compose.yml:
env_file:
- ../control-plane/.env
Auth flow
sequenceDiagram
participant Browser
participant ServerUI
participant GpuFanAgent
Browser->>ServerUI: X-API-Key: API_KEY
ServerUI->>GpuFanAgent: X-API-Key: API_KEY (ten sam)
GpuFanAgent-->>ServerUI: status JSON
ServerUI-->>Browser: proxy response
Poza scope
Sekrety workloadów Docker (LOCALAI_API_KEY, HF_TOKEN, INITIAL_ADMIN_PASSWORD, …) pozostają w stacks/<nazwa>/.env — edycja portów przez Server UI bez zmian.
Pliki zmienione (implementacja)
stacks/control-plane/—.env.example,env_loader.pystacks/server-ui/scripts/setup-control-plane-env.shserver-ui.service,gpu-fan.serviceserver-ui/app.py,gpu_fan_proxy.py,gpu-fan/fan_daemon.py,gpu-fan/app.py- Instalatory:
install-control-plane.sh,install.sh,install-docker.sh,gpu-fan/install.sh - Skrypty dev:
start.sh,deploy-gpu-fan-fix.sh,restart-stack.sh,enable-lan.sh,status.sh
Troubleshooting — Invalid API key
- Klucz tylko z
/opt/control-plane/.env(sudo grep ^API_KEY= …) - UI: Zapisz → Sprawdź klucz
- Sync:
sudo bash stacks/server-ui/scripts/setup-control-plane-env.sh - Tutorial:
manual-tutorial/04a-api-key.md
Legacy
Stare pliki /opt/server-ui/.env i /opt/gpu-fan/.env nie są już czytane przez systemd. Po migracji można je usunąć (backup w .env.bak.*).