# ollama-manager

Gestisce il ciclo di vita dei modelli Ollama e li espone in modo sicuro via API compatibile OpenAI.

## Funzionalità

- **Model management** (admin): lista, pull con progresso SSE, delete, show
- **Token management** (admin): genera, revoca e lista token di accesso (SHA-256 hashed in DB)
- **Alias management** (admin): mappa sottodomini a nomi modello (`gemma4b` → `gemma4:e2b`)
- **Inference proxy** (`/v1/*`): compatibile OpenAI, richiede Bearer token

## Routing per sottodominio

Il microservizio legge l'header `X-Forwarded-Host` (o `Host`) per determinare il modello:

```
gemma4b.vinovalab.ai  →  Bearer olm_xxx  →  ollama-manager  →  ollama (model: gemma4:e2b)
```

La mappatura sottodominio → model name si gestisce via `/api/admin/aliases`.

## Variabili d'ambiente

| Variabile | Default | Descrizione |
|---|---|---|
| `PORT` | `5029` | Porta HTTP |
| `DATABASE_URL` | — | Connessione PostgreSQL (per token e alias) |
| `REDIS_HOST` | `redis` | Host Redis (cache token) |
| `REDIS_PORT` | `6379` | Porta Redis |
| `REDIS_PASSWORD` | — | Password Redis |
| `OLLAMA_BASE_URL` | `http://ollama:11434` | URL base Ollama |
| `OLLAMA_ADMIN_SUBDOMAIN` | `ollama` | Sottodominio riservato all'admin (non proxy) |

## API Routes

### Admin (richiede autenticazione interna)

```
GET    /api/admin/models            Lista modelli installati
GET    /api/admin/models/running    Modelli in esecuzione (VRAM)
GET    /api/admin/models/:name      Dettagli modello
POST   /api/admin/models/pull       Pull modello (SSE progress stream)
DELETE /api/admin/models/:name      Elimina modello

GET    /api/admin/tokens            Lista token di accesso
POST   /api/admin/tokens            Crea token (restituisce il plaintext una volta sola)
DELETE /api/admin/tokens/:id        Revoca token

GET    /api/admin/aliases           Lista alias sottodominio → modello
POST   /api/admin/aliases           Crea alias
DELETE /api/admin/aliases/:id       Elimina alias
```

### Inference proxy (richiede Bearer token `olm_*`)

```
GET    /v1/models
POST   /v1/chat/completions
POST   /v1/completions
POST   /v1/embeddings
```

## Token flow

1. Admin genera token via `POST /api/admin/tokens`
2. Il server genera `olm_<64hex>`, salva `SHA256(token)` in DB, restituisce il plaintext **una volta sola**
3. Il client chiama `/v1/chat/completions` con `Authorization: Bearer olm_xxx`
4. ollama-manager verifica (Redis cache 60s → fallback DB), poi proxya verso Ollama
