500 lines
13 KiB
Markdown
500 lines
13 KiB
Markdown
# LLM Monitor - Dashboard Ollama
|
|
|
|
Una dashboard web moderna e intuitiva per monitorare e gestire i modelli LLM caricati in **Ollama**. Visualizza i modelli disponibili, i dettagli dei caricamenti e accedi ai dati via API Ollama direttamente da una web app elegante.
|
|
|
|
## 🎯 Caratteristiche
|
|
|
|
- ✨ **Dashboard intuitiva** - Visualizza in tempo reale i modelli disponibili e in esecuzione su Ollama
|
|
- 📊 **Monitoraggio modelli** - Dettagli completi di ogni modello (nome, dimensione, memoria, stato)
|
|
- 🧩 **Dettagli accordion on click** - Clic su una card per esplorare i dati `ollama show` in pannelli collassabili (dettagli, parametri, template, modelfile, licenza)
|
|
- 🖥️ **Multi-server** - Gestione di più istanze Ollama con switch istantaneo (pagina `/servers`)
|
|
- 🏃 **Modelli in esecuzione** - Pagina dedicata `/models-running` con VRAM, tempo rimanente e backend GPU/CPU
|
|
- 📱 **PWA** - Installabile come app desktop/mobile con Service Worker e cache offline
|
|
- 🔌 **API REST documentata** - Documentazione interattiva con Swagger/OpenAPI
|
|
- 🎨 **UI moderna** - Interfaccia dark-mode realizzata con TailwindCSS
|
|
- 🐳 **Docker ready** - Container sempre acceso (restart: unless-stopped)
|
|
- ⚡ **Performance** - FastAPI + uVicorn, aggiornamenti ogni 30s via Web Worker senza bloccare l'UI
|
|
- 🔐 **Configurazione flessibile** - File `.env` per personalizzazione
|
|
|
|
## 📋 Requisiti
|
|
|
|
- **Python** 3.10+
|
|
- **Ollama** installato e in esecuzione
|
|
- **Docker** (opzionale, per containerizzazione)
|
|
- **Docker Compose** (opzionale)
|
|
|
|
## 🚀 Installazione Rapida
|
|
|
|
### 1. Clonare il repository
|
|
|
|
```bash
|
|
git clone https://github.com/LucaSacchiNet/llm-monitor.git
|
|
cd llm-monitor
|
|
```
|
|
|
|
### 2. Configurare l'ambiente
|
|
|
|
Copia il file di esempio:
|
|
|
|
```bash
|
|
cp env.example .env
|
|
```
|
|
|
|
Modifica `.env` con i tuoi parametri (vedi [Configurazione](#configurazione)):
|
|
|
|
```bash
|
|
nano .env
|
|
```
|
|
|
|
### 3. Installare le dipendenze
|
|
|
|
#### Opzione A: Ambiente virtuale (Sviluppo)
|
|
|
|
```bash
|
|
python3 -m venv venv
|
|
source venv/bin/activate # Su Windows: venv\Scripts\activate
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
#### Opzione B: Docker (Produzione)
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
### 4. Avviare l'applicazione
|
|
|
|
#### Modalità sviluppo
|
|
|
|
```bash
|
|
python3 -m uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
|
```
|
|
|
|
#### Modalità produzione
|
|
|
|
```bash
|
|
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
|
|
```
|
|
|
|
## ⚙️ Configurazione
|
|
|
|
Crea un file `.env` nella root del progetto (copia da `env.example`):
|
|
|
|
```env
|
|
# Ollama Configuration
|
|
OLLAMA_HOST=http://localhost:11434
|
|
OLLAMA_TIMEOUT=30
|
|
|
|
# API Configuration
|
|
API_HOST=0.0.0.0
|
|
API_PORT=8000
|
|
API_WORKERS=4
|
|
ENABLE_MODEL_RW_API=false
|
|
|
|
# CORS Configuration
|
|
CORS_ORIGINS=http://localhost:3000,http://localhost:5173
|
|
|
|
# Logging
|
|
LOG_LEVEL=INFO
|
|
|
|
# Environment
|
|
ENVIRONMENT=development
|
|
```
|
|
|
|
### Variabili disponibili
|
|
|
|
| Variabile | Default | Descrizione |
|
|
|-----------|---------|-------------|
|
|
| `OLLAMA_HOST` | `http://localhost:11434` | URL della API Ollama |
|
|
| `OLLAMA_TIMEOUT` | `30` | Timeout (secondi) per le richieste |
|
|
| `API_HOST` | `0.0.0.0` | Host su cui esporre l'API |
|
|
| `API_PORT` | `8000` | Porta dell'API |
|
|
| `API_WORKERS` | `4` | Worker processes |
|
|
| `ENABLE_MODEL_RW_API` | `false` | Abilita endpoint `POST/DELETE` sui modelli |
|
|
| `CORS_ORIGINS` | `http://localhost:3000` | Origini CORS consentite |
|
|
| `LOG_LEVEL` | `INFO` | Livello di logging |
|
|
| `ENVIRONMENT` | `development` | Ambiente (development/production) |
|
|
|
|
## 📚 API Swagger
|
|
|
|
La documentazione interattiva dell'API è disponibile automaticamente:
|
|
|
|
- **Swagger UI**: http://localhost:8000/docs
|
|
- **ReDoc**: http://localhost:8000/redoc
|
|
|
|
### Endpoint principali
|
|
|
|
#### Recuperare modelli caricati
|
|
|
|
```bash
|
|
GET /api/v1/models
|
|
```
|
|
|
|
**Risposta:**
|
|
|
|
```json
|
|
{
|
|
"models": [
|
|
{
|
|
"name": "llama2",
|
|
"digest": "abc123...",
|
|
"size": 3825922048,
|
|
"modified_at": "2024-01-15T10:30:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### Dettagli di un modello specifico
|
|
|
|
```bash
|
|
GET /api/v1/models/{model_name}
|
|
```
|
|
|
|
#### Dettagli estesi da Ollama show
|
|
|
|
```bash
|
|
GET /api/v1/models/{model_name}/show
|
|
```
|
|
|
|
#### Health check API Ollama
|
|
|
|
```bash
|
|
GET /api/v1/health
|
|
```
|
|
|
|
#### Endpoint R/W modelli (opzionali)
|
|
|
|
Per impostazione predefinita gli endpoint di scrittura sono **disabilitati** e non disponibili.
|
|
|
|
```bash
|
|
POST /api/v1/models/{model_name}/pull
|
|
DELETE /api/v1/models/{model_name}
|
|
```
|
|
|
|
Per abilitarli, imposta nel file `.env`:
|
|
|
|
```env
|
|
ENABLE_MODEL_RW_API=true
|
|
```
|
|
|
|
**Risposta:**
|
|
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"ollama_version": "0.1.0",
|
|
"uptime_seconds": 3600
|
|
}
|
|
```
|
|
|
|
### Test API con cURL
|
|
|
|
```bash
|
|
# Ottenere i modelli
|
|
curl http://localhost:8000/api/v1/models
|
|
|
|
# Ottenere info su un modello
|
|
curl http://localhost:8000/api/v1/models/llama2
|
|
|
|
# Ottenere dettagli estesi show
|
|
curl http://localhost:8000/api/v1/models/llama2/show
|
|
|
|
# Health check
|
|
curl http://localhost:8000/api/v1/health
|
|
```
|
|
|
|
### Comportamento dashboard
|
|
|
|
- Al refresh della lista modelli, per ogni modello viene recuperato anche il dettaglio `show`.
|
|
- I dati vengono salvati in localStorage nella chiave `llm_monitor_models` (campo `showByModel`).
|
|
- Cliccando su una card modello, la dashboard mostra i dettagli `show` senza ricaricare la pagina.
|
|
|
|
## 🐳 Docker
|
|
|
|
### Build dell'immagine
|
|
|
|
```bash
|
|
docker build -t llm-monitor:latest .
|
|
```
|
|
|
|
### Eseguire il container
|
|
|
|
```bash
|
|
docker run -d \
|
|
--name llm-monitor \
|
|
-p 8000:8000 \
|
|
--env-file .env \
|
|
--network host \
|
|
llm-monitor:latest
|
|
```
|
|
|
|
> ⚠️ **Nota**: `--network host` consente al container di accedere a Ollama su localhost
|
|
|
|
### Docker Compose
|
|
|
|
Usa il file `docker-compose.yml` fornito:
|
|
|
|
```bash
|
|
# Avviare i servizi
|
|
docker compose up -d
|
|
|
|
# Rebuild completo senza cache (consigliato dopo modifiche UI/Tailwind)
|
|
docker compose build --no-cache
|
|
|
|
# Verificare che il CSS compilato non sia vuoto
|
|
docker exec llm-monitor-app wc -l /app/app/web/static/css/output.css
|
|
|
|
# Visualizzare i log
|
|
docker compose logs -f llm-monitor
|
|
|
|
# Fermare i servizi
|
|
docker compose down
|
|
|
|
# Riavviare
|
|
docker compose restart llm-monitor
|
|
```
|
|
|
|
### Deploy consigliato (Tailwind-safe)
|
|
|
|
Se l'interfaccia appare senza stili o una modale non si posiziona correttamente, usa il deploy con rebuild no-cache e verifica CSS:
|
|
|
|
```bash
|
|
cd /opt/llm-monitor
|
|
docker compose down
|
|
docker compose build --no-cache
|
|
docker compose up -d
|
|
sleep 5
|
|
docker exec llm-monitor-app wc -l /app/app/web/static/css/output.css
|
|
```
|
|
|
|
In alternativa dal repository:
|
|
|
|
```bash
|
|
make deploy-no-cache
|
|
```
|
|
|
|
### Tailwind Build Process
|
|
|
|
- Lo stage `css-builder` del Dockerfile installa dipendenze Node con `npm ci`.
|
|
- Prima della build Tailwind vengono copiati template HTML e JS usati dal content scan.
|
|
- Dopo `npm run tailwind:build` una verifica bloccante controlla che `output.css` esista e abbia almeno 100 linee.
|
|
- Lo stage runtime copia `output.css` compilato da `css-builder` con `COPY --from=css-builder`.
|
|
|
|
### Troubleshooting UI
|
|
|
|
Se la modale non appare o i componenti sembrano "unstyled":
|
|
|
|
1. Esegui `docker compose build --no-cache`.
|
|
2. Riavvia con `docker compose up -d`.
|
|
3. Verifica CSS compilato: `docker exec llm-monitor-app wc -l /app/app/web/static/css/output.css`.
|
|
4. Se il numero linee e `< 100`, la build Tailwind non e riuscita correttamente.
|
|
|
|
### Container sempre acceso
|
|
|
|
Il container `llm-monitor` rimarrà in esecuzione fino al suo arresto manuale:
|
|
|
|
```bash
|
|
# Fermare
|
|
docker compose stop llm-monitor
|
|
# oppure
|
|
docker stop llm-monitor
|
|
|
|
# Riavviare
|
|
docker compose start llm-monitor
|
|
# oppure
|
|
docker start llm-monitor
|
|
```
|
|
|
|
## 📁 Struttura del Progetto
|
|
|
|
```
|
|
llm-monitor/
|
|
├── main.py # Entry point dell'applicazione
|
|
├── requirements.txt # Dipendenze Python
|
|
├── requirements-dev.txt # Dipendenze sviluppo (pytest, black, flake8…)
|
|
├── env.example # Esempio di configurazione
|
|
├── Dockerfile # Build multi-stage (Node CSS + Python runtime)
|
|
├── docker-compose.yml # Composizione servizi
|
|
├── package.json # Script Node (Tailwind, Playwright)
|
|
├── tailwind.config.js # Configurazione TailwindCSS
|
|
├── playwright.config.js # Configurazione test E2E
|
|
├── Makefile # Comandi rapidi (dev, test, deploy…)
|
|
├── README.md # Questo file
|
|
├── CONTRIBUTING.md # Guida ai contributi
|
|
│
|
|
├── app/
|
|
│ ├── config.py # Configurazione via variabili d'ambiente
|
|
│ │
|
|
│ ├── api/
|
|
│ │ ├── models.py # Endpoint modelli (/api/v1/models)
|
|
│ │ └── health.py # Endpoint health (/api/v1/health)
|
|
│ │
|
|
│ ├── services/
|
|
│ │ └── ollama.py # Client HTTP verso Ollama
|
|
│ │
|
|
│ └── web/
|
|
│ ├── static/
|
|
│ │ ├── css/
|
|
│ │ │ ├── input.css # Sorgente Tailwind
|
|
│ │ │ └── output.css # CSS compilato (generato)
|
|
│ │ └── js/
|
|
│ │ ├── app.js # App principale (dashboard modelli)
|
|
│ │ ├── servers.js # Pagina gestione server
|
|
│ │ ├── models-running.js # Pagina modelli in esecuzione
|
|
│ │ ├── data-sync.worker.js # Web Worker sincronizzazione dati
|
|
│ │ ├── server-config.js # Utilità multi-server e localStorage
|
|
│ │ ├── pwa-register.js # Registrazione Service Worker
|
|
│ │ └── service-worker.js # PWA Service Worker (cache-first)
|
|
│ └── templates/
|
|
│ ├── index.html # Dashboard modelli disponibili
|
|
│ ├── servers.html # Gestione istanze Ollama
|
|
│ └── models_running.html # Modelli attualmente in esecuzione
|
|
│
|
|
├── docs/
|
|
│ ├── PRD.md # Product Requirements Document
|
|
│ ├── DEVELOPMENT.md # Guida al setup e sviluppo locale
|
|
│ └── WEB_WORKERS.md # Architettura Web Worker e PWA
|
|
│
|
|
├── scripts/
|
|
│ ├── deploy-no-cache.sh # Deploy Docker con rebuild forzato
|
|
│ └── verify-tailwind-css.sh # Verifica CSS compilato in container
|
|
│
|
|
└── tests/
|
|
├── test_api.py # Unit test endpoint FastAPI
|
|
├── test_ollama.py # Unit test client Ollama
|
|
└── e2e/
|
|
└── cache-navigation.spec.js # Test E2E Playwright (cache/PWA)
|
|
```
|
|
|
|
## 🛠️ Sviluppo
|
|
|
|
### Setup locale
|
|
|
|
```bash
|
|
# Clonare il repo
|
|
git clone https://github.com/LucaSacchiNet/llm-monitor.git
|
|
cd llm-monitor
|
|
|
|
# Ambiente virtuale
|
|
python3 -m venv venv
|
|
source venv/bin/activate
|
|
|
|
# Installare dipendenze + dev
|
|
pip install -r requirements.txt
|
|
pip install -r requirements-dev.txt # black, pytest, flake8, etc.
|
|
```
|
|
|
|
### Comandi utili
|
|
|
|
```bash
|
|
# Formattare codice
|
|
black app/ tests/ main.py
|
|
|
|
# Linting
|
|
flake8 app/ tests/ main.py
|
|
|
|
# Test
|
|
pytest tests/ -v
|
|
|
|
# Test con coverage
|
|
pytest tests/ --cov=app
|
|
|
|
# Browser E2E test (cache-first navigation)
|
|
OLLAMA_HOST=http://192.168.254.115:11434 npm run test:e2e
|
|
|
|
# Hot reload durante sviluppo
|
|
uvicorn main:app --reload
|
|
```
|
|
|
|
### Compilare TailwindCSS
|
|
|
|
```bash
|
|
# Installare dipendenze Node (opzionale)
|
|
npm install
|
|
|
|
# Generare CSS in modalità développement
|
|
npm run tailwind:dev
|
|
|
|
# Build per produzione
|
|
npm run tailwind:build
|
|
```
|
|
|
|
## 🐛 Troubleshooting
|
|
|
|
### Errore: "Cannot connect to Ollama"
|
|
|
|
- Verificare che Ollama sia in esecuzione: `curl http://localhost:11434/api/tags`
|
|
- Controllare che l'indirizzo in `.env` sia corretto (`OLLAMA_HOST`)
|
|
- Se usi Docker, assicurati che il container abbia accesso a Ollama (vedi [Docker](#docker))
|
|
|
|
### Errore: "Port 8000 already in use"
|
|
|
|
```bash
|
|
# Cambiare la porta in .env
|
|
API_PORT=8001
|
|
|
|
# Oppure liberare la porta
|
|
lsof -ti :8000 | xargs kill -9
|
|
```
|
|
|
|
### Dashboard lenta
|
|
|
|
- Verificare lo stato di Ollama
|
|
- Aumentare `OLLAMA_TIMEOUT` in `.env`
|
|
- Controllare i log: `docker compose logs -f llm-monitor`
|
|
|
|
## 📄 Dipendenze Principali
|
|
|
|
- **FastAPI** - Framework web moderno
|
|
- **uVicorn** - Server ASGI ad alte prestazioni
|
|
- **Pydantic** - Validazione dati
|
|
- **Requests** - Client HTTP
|
|
- **Jinja2** - Template HTML
|
|
- **TailwindCSS** - Utility-first CSS
|
|
|
|
## 📜 Licenza
|
|
|
|
Questo progetto e distribuito con **licenza proprietaria** (tutti i diritti riservati).
|
|
|
|
Autore e detentore esclusivo di tutti i diritti: **Luca Sacchi Ricciardi**.
|
|
|
|
- Uso consentito gratuitamente
|
|
- Software fornito "AS IS"
|
|
- Nessuna garanzia
|
|
- Nessun supporto o manutenzione obbligatori
|
|
- Foro competente esclusivo: Milano, Italia
|
|
|
|
Dettagli completi:
|
|
|
|
- `LICENSE` (notice principale)
|
|
- `LICENSE.en.txt` (testo completo in inglese)
|
|
- `LICENSE.it.txt` (testo completo in italiano)
|
|
|
|
## 🤝 Contribuire
|
|
|
|
Le pull request sono benvenute! Per cambiamenti importanti, apri prima un issue per discutere i cambiamenti proposti.
|
|
|
|
### Processo di contribuzione
|
|
|
|
1. Fork il repository
|
|
2. Crea un branch (`git checkout -b feature/amazing-feature`)
|
|
3. Commit i cambiamenti (`git commit -m 'Add amazing feature'`)
|
|
4. Push al branch (`git push origin feature/amazing-feature`)
|
|
5. Apri una Pull Request
|
|
|
|
## 📞 Supporto
|
|
|
|
Per domande o segnalazioni di bug, apri un **Issue** nel repository oppure contatta l'autore:
|
|
|
|
- luca.sacchi@gmail.com
|
|
- luca@lucasacchi.net
|
|
|
|
---
|
|
|
|
**Autore: Luca Sacchi Ricciardi ([LucaSacchi.Net](https://lucasacchi.net), luca.sacchi@gmail.com, luca@lucasacchi.net)**
|
|
|
|
**Versione**: 1.1.0
|
|
**Ultima modifica**: Aprile 2026
|
|
**Status**: 🟢 Active
|