351 lines
7.6 KiB
Markdown
351 lines
7.6 KiB
Markdown
# Monitor RPi Rack
|
|
|
|
Aplicacion web local para monitorizar un rack de Raspberry Pi mediante SSH. Corre en un contenedor Docker dedicado y expone un dashboard accesible por navegador.
|
|
|
|
## Arquitectura
|
|
|
|
```text
|
|
Navegador
|
|
dashboard.html / config.html
|
|
|
|
|
| HTTP API
|
|
v
|
|
Contenedor monitor-rpi
|
|
|
|
|
| SSH con usuario/password o clave privada
|
|
v
|
|
Raspberry Pi activas
|
|
```
|
|
|
|
El backend mantiene el ultimo estado en memoria. El dashboard consulta ese estado, pero no abre conexiones SSH directamente.
|
|
|
|
## Rutas Principales
|
|
|
|
- Dashboard: `http://192.168.0.53:8787/dashboard.html`
|
|
- Configuracion: `http://192.168.0.53:8787/config.html`
|
|
- API estado: `http://192.168.0.53:8787/api/status`
|
|
|
|
Credenciales HTTP actuales:
|
|
|
|
```text
|
|
usuario: admin
|
|
password: monitor-rpi-2026
|
|
```
|
|
|
|
## Configuracion Persistente
|
|
|
|
La configuracion vive en:
|
|
|
|
```text
|
|
/home/yamaray/docker/monitorRPi/data/config.json
|
|
```
|
|
|
|
Dentro del contenedor se lee como:
|
|
|
|
```text
|
|
/data/config.json
|
|
```
|
|
|
|
## Parametros Generales
|
|
|
|
### `mockMode`
|
|
|
|
Si es `true`, el sistema genera datos simulados. Si es `false`, consulta las Raspberry reales por SSH.
|
|
|
|
### `refreshIntervalSeconds`
|
|
|
|
Intervalo activo de escaneo cuando hay al menos un dashboard visible. Por defecto: `30`.
|
|
|
|
### `idleScanIntervalSeconds`
|
|
|
|
Intervalo lento de escaneo cuando no hay dashboards visibles. Por defecto: `300`.
|
|
|
|
### `sshTimeoutSeconds`
|
|
|
|
Tiempo maximo permitido para completar cada consulta SSH. Por defecto: `8`.
|
|
|
|
### `temperatureThresholdsC`
|
|
|
|
Umbrales de color para temperaturas:
|
|
|
|
```json
|
|
{
|
|
"warning": 60,
|
|
"hot": 70,
|
|
"critical": 80
|
|
}
|
|
```
|
|
|
|
### `metricThresholdsPercent`
|
|
|
|
Umbrales por metrica para barras de CPU, RAM y disco.
|
|
|
|
Valores actuales recomendados:
|
|
|
|
```json
|
|
{
|
|
"cpu": { "warning": 60, "hot": 75, "critical": 90 },
|
|
"memory": { "warning": 70, "hot": 85, "critical": 95 },
|
|
"disk": { "warning": 70, "hot": 85, "critical": 95 }
|
|
}
|
|
```
|
|
|
|
## Parametros Por Dispositivo
|
|
|
|
### `active`
|
|
|
|
Si es `true`, el backend consulta ese dispositivo. Si es `false`, aparece como inactivo y no se abre SSH.
|
|
|
|
### `id`
|
|
|
|
Identificador interno unico del dispositivo. Se usa para tracking interno y calculos como tasas de red.
|
|
|
|
### `name`
|
|
|
|
Nombre visible en el dashboard.
|
|
|
|
### `host`
|
|
|
|
IP o nombre DNS usado para conectar por SSH.
|
|
|
|
### `port`
|
|
|
|
Puerto SSH. Normalmente `22`; en Home Assistant puede ser `2222` si se usa un add-on SSH.
|
|
|
|
### `username`
|
|
|
|
Usuario SSH.
|
|
|
|
### `password`
|
|
|
|
Password SSH. Se guarda en `config.json`, por lo que el archivo debe permanecer protegido. Si `privateKeyPath` esta configurado, la clave privada tiene prioridad y no se usa `password`.
|
|
|
|
### `privateKeyPath`
|
|
|
|
Ruta de la clave privada SSH dentro del contenedor o del host donde corre el monitor. Debe apuntar a una clave privada legible por el proceso del monitor. Para uso en Docker, monta la clave o una carpeta `.ssh` dentro del contenedor. Las claves con passphrase requieren agente SSH disponible; para monitorizacion unattended suele usarse una clave sin passphrase protegida por permisos de archivo.
|
|
|
|
## Autenticacion SSH por Clave Privada
|
|
|
|
El monitor soporta dos metodos de autenticacion por dispositivo:
|
|
|
|
- Password SSH: usar `password` y dejar `privateKeyPath` vacio.
|
|
- Clave privada: dejar `password` vacio y configurar `privateKeyPath`.
|
|
|
|
Cuando `privateKeyPath` tiene valor, el backend usa clave privada y no usa el password.
|
|
|
|
### 1. Guardar la clave privada en el volumen del monitor
|
|
|
|
En la RPi donde corre el contenedor, guarda las claves en:
|
|
|
|
```text
|
|
/home/yamaray/docker/monitorRPi/ssh
|
|
```
|
|
|
|
Ejemplo:
|
|
|
|
```text
|
|
/home/yamaray/docker/monitorRPi/ssh/carabanes_monitor_ed25519
|
|
/home/yamaray/docker/monitorRPi/ssh/carabanes_monitor_ed25519.pub
|
|
```
|
|
|
|
La clave privada debe quedar protegida:
|
|
|
|
```bash
|
|
chmod 700 /home/yamaray/docker/monitorRPi/ssh
|
|
chmod 600 /home/yamaray/docker/monitorRPi/ssh/carabanes_monitor_ed25519
|
|
```
|
|
|
|
El `docker-compose.yml` debe montar esa carpeta dentro del contenedor:
|
|
|
|
```yaml
|
|
volumes:
|
|
- /home/yamaray/docker/monitorRPi/app:/app:ro
|
|
- /home/yamaray/docker/monitorRPi/data:/data
|
|
- /home/yamaray/docker/monitorRPi/ssh:/ssh:ro
|
|
```
|
|
|
|
Dentro de la configuracion del dispositivo, la ruta debe ser la ruta vista por el contenedor:
|
|
|
|
```json
|
|
"password": "",
|
|
"privateKeyPath": "/ssh/carabanes_monitor_ed25519"
|
|
```
|
|
|
|
### 2. Instalar la clave publica en la Raspberry destino
|
|
|
|
En el dispositivo remoto, la clave publica debe agregarse al usuario SSH correspondiente.
|
|
|
|
Ejemplo para usuario `pi`:
|
|
|
|
```bash
|
|
mkdir -p ~/.ssh
|
|
chmod 700 ~/.ssh
|
|
nano ~/.ssh/authorized_keys
|
|
chmod 600 ~/.ssh/authorized_keys
|
|
```
|
|
|
|
En `authorized_keys` pega el contenido de la clave publica:
|
|
|
|
```text
|
|
carabanes_monitor_ed25519.pub
|
|
```
|
|
|
|
El archivo correcto en Linux/OpenSSH es:
|
|
|
|
```text
|
|
~/.ssh/authorized_keys
|
|
```
|
|
|
|
No es `authorised_keys`.
|
|
|
|
### 3. Probar la conexion desde el contenedor
|
|
|
|
Una vez montada la clave, puedes probar desde la RPi host:
|
|
|
|
```bash
|
|
docker exec -it monitor-rpi ssh -i /ssh/carabanes_monitor_ed25519 -o IdentitiesOnly=yes pi@HOST_REMOTO
|
|
```
|
|
|
|
Si el dispositivo usa un puerto distinto:
|
|
|
|
```bash
|
|
docker exec -it monitor-rpi ssh -i /ssh/carabanes_monitor_ed25519 -o IdentitiesOnly=yes -p 34000 pi@192.168.0.1
|
|
```
|
|
|
|
Si la conexion funciona sin pedir password, el monitor tambien podra consultar ese dispositivo.
|
|
|
|
### `model`
|
|
|
|
Modelo visible: `RPi 3`, `RPi 4`, `RPi 5`.
|
|
|
|
### `role`
|
|
|
|
Funcion del dispositivo: Docker, Home Assistant, MQTT, Nginx, Gitea, etc.
|
|
|
|
### `location`
|
|
|
|
Ubicacion fisica o logica. Actualmente se muestra en la tarjeta.
|
|
|
|
## Metricas Recogidas
|
|
|
|
Por SSH se leen datos de solo lectura:
|
|
|
|
- Temperatura CPU
|
|
- Uso CPU
|
|
- Uso RAM
|
|
- Uso disco raiz `/`
|
|
- Load average
|
|
- Uptime
|
|
- Docker instalado
|
|
- Contenedores Docker activos
|
|
- Contenedores Docker detenidos
|
|
- Contenedores Docker unhealthy
|
|
- Interfaz de red principal
|
|
- Tipo de conexion: Cable/WiFi
|
|
- Velocidad nominal si existe
|
|
- Trafico RX/TX calculado entre scans
|
|
|
|
## Clientes Activos
|
|
|
|
El dashboard envia heartbeat al backend cuando esta visible.
|
|
|
|
Comportamiento:
|
|
|
|
```text
|
|
0 clientes visibles -> escaneo lento idleScanIntervalSeconds
|
|
1+ clientes visibles -> escaneo activo refreshIntervalSeconds
|
|
```
|
|
|
|
El navegador integrado de Codex se ignora para no alterar el conteo de clientes reales.
|
|
|
|
## API
|
|
|
|
Todas las llamadas requieren autenticacion HTTP Basic.
|
|
|
|
### `GET /api/status`
|
|
|
|
Devuelve ultimo estado conocido.
|
|
|
|
Incluye:
|
|
|
|
- `mockMode`
|
|
- `refreshIntervalSeconds`
|
|
- `idleScanIntervalSeconds`
|
|
- `activeClients`
|
|
- `currentScanIntervalSeconds`
|
|
- `temperatureThresholdsC`
|
|
- `metricThresholdsPercent`
|
|
- `summary`
|
|
- `devices`
|
|
- `clients`
|
|
|
|
Ejemplo PowerShell:
|
|
|
|
```powershell
|
|
$pair = 'admin:monitor-rpi-2026'
|
|
$token = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($pair))
|
|
Invoke-RestMethod http://192.168.0.53:8787/api/status -Headers @{Authorization="Basic $token"}
|
|
```
|
|
|
|
### `GET /api/config`
|
|
|
|
Devuelve la configuracion actual.
|
|
|
|
Nota: actualmente devuelve tambien credenciales porque `config.html` permite editarlas. Protege el acceso HTTP y el archivo `config.json`.
|
|
|
|
### `POST /api/config`
|
|
|
|
Guarda la configuracion completa y reinicia el ciclo de escaneo.
|
|
|
|
### `POST /api/reload`
|
|
|
|
Recarga `config.json` desde disco.
|
|
|
|
### `POST /api/scan-now`
|
|
|
|
Fuerza un scan inmediato de todos los dispositivos activos.
|
|
|
|
### `POST /api/client-heartbeat`
|
|
|
|
Usado por el dashboard para avisar que hay un cliente visible.
|
|
|
|
Body:
|
|
|
|
```json
|
|
{
|
|
"clientId": "client-id"
|
|
}
|
|
```
|
|
|
|
### `POST /api/clients/clear`
|
|
|
|
Limpia la lista de clientes activos en memoria.
|
|
|
|
## Docker
|
|
|
|
Ruta en la RPi:
|
|
|
|
```text
|
|
/home/yamaray/docker/monitorRPi/
|
|
```
|
|
|
|
Stack:
|
|
|
|
```text
|
|
/home/yamaray/docker/monitorRPi/docker-compose.yml
|
|
```
|
|
|
|
Reiniciar:
|
|
|
|
```bash
|
|
cd /home/yamaray/docker/monitorRPi
|
|
docker compose restart monitor-rpi
|
|
```
|
|
|
|
Reconstruir:
|
|
|
|
```bash
|
|
cd /home/yamaray/docker/monitorRPi
|
|
docker compose up -d --build
|
|
```
|