✨ Nuove funzionalità: - Nuovo endpoint API REST /api/v1/query (GET+POST) per consumo programmatico - Campo speakable_text ottimizzato per sintesi vocale (Alexa, Google Home) - Funzione strip_markdown() per conversione Markdown → plain text TTS - Supporto CORS per accesso cross-origin - UI responsive mobile-first con micro-interazioni e stati - Nuovo pulsante 'Nuova ricerca' e metadata bar 📚 Documentazione completa: - docs/ARCHITECTURE.md — architettura di sistema, stack, componenti - docs/FLOW.md — diagrammi Mermaid della pipeline e flussi - docs/API.md — documentazione endpoint REST con esempi curl - docs/WIKI.md — FAQ, glossario, roadmap - docs/DEPLOYMENT.md — guida deployment (Gunicorn, Nginx, Docker, systemd) - docs/CONTRIBUTING.md — guida alla contribuzione 🔧 Migliorie tecniche: - Pipeline di ricerca condivisa in _run_search_pipeline() - Gestione errori Gemini migliorata con _clean_error() - Sanitizzazione HTML con allowlist per prevenzione XSS - .env.example completo con commenti 🧪 Test: 109/109 passati
9.2 KiB
9.2 KiB
🚀 Sibilla — Guida al Deployment
Versione: 0.2.0
Ultimo aggiornamento: 18 Luglio 2026
Indice
- Prerequisiti
- Installazione rapida
- Configurazione
- Avvio
- Deployment in produzione
- Docker Compose
- Reverse Proxy
- Systemd Service
- Monitoraggio
- Troubleshooting
Prerequisiti
Software
| Componente | Versione minima | Note |
|---|---|---|
| Python | 3.10+ | |
| pip | 21.0+ | |
| Git | — | Opzionale, per clonare il repo |
Servizi esterni
| Servizio | Obbligatorio? | Come ottenerlo |
|---|---|---|
| Google API Key | ✅ Sì | Google AI Studio |
| Degoog | Consigliato | docker run -d -p 4444:4444 ghcr.io/degoog-org/degoog:latest |
| SearXNG | No (fallback) | docker run -d -p 8080:8080 searxng/searxng |
| DuckDuckGo | No (automatico) | Nessuna configurazione necessaria |
Installazione rapida
# 1. Clona il repository
git clone https://github.com/tuo-user/sibilla.git
cd sibilla
# 2. Crea ambiente virtuale
python3 -m venv .venv
source .venv/bin/activate # Linux/Mac
# .venv\Scripts\activate # Windows
# 3. Installa dipendenze
pip install -e ".[dev]"
# 4. Configura
cp .env.example .env # se esiste, altrimenti crealo
nano .env # Inserisci GOOGLE_API_KEY
# 5. Avvia (sviluppo)
sibilla
# → http://127.0.0.1:5000
Configurazione
Crea un file .env nella root del progetto:
# ═══════════════════════════════════════════════════════════════
# Sibilla Configuration
# ═══════════════════════════════════════════════════════════════
# Google Gemini API key (obbligatoria)
GOOGLE_API_KEY=AIzaSyD-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Flask secret key (cambiala in produzione!)
SECRET_KEY=una-chiave-segreta-molto-lunga-e-casuale
# ── Server ───────────────────────────────────────────────────
# Host e porta del server Flask
SIBILLA_HOST=127.0.0.1
SIBILLA_PORT=5000
# Debug mode (0 = off, 1 = on)
# NON usare in produzione!
SIBILLA_DEBUG=1
# ── Search Engines ────────────────────────────────────────────
# Degoog (primary)
DEGOOG_URL=http://localhost:4444
# SearXNG (secondary)
SEARXNG_URL=http://localhost:8080
# DuckDuckGo fallback (1 = on, 0 = off)
SIBILLA_DDG_FALLBACK=1
Variabili d'ambiente complete
| Variabile | Default | Descrizione |
|---|---|---|
GOOGLE_API_KEY |
"" |
Obbligatoria. API key di Google AI |
SECRET_KEY |
"dev-secret-key-change-me" |
Secret key Flask |
SIBILLA_HOST |
"127.0.0.1" |
Host su cui ascoltare |
SIBILLA_PORT |
"5000" |
Porta del server |
SIBILLA_DEBUG |
"1" |
Debug mode (0/1) |
DEGOOG_URL |
"http://localhost:4444" |
URL dell'istanza Degoog |
SEARXNG_URL |
"http://localhost:8080" |
URL dell'istanza SearXNG |
SIBILLA_DDG_FALLBACK |
"1" |
Abilita fallback DuckDuckGo (0/1) |
Avvio
Sviluppo
# Modo 1: CLI
sibilla
# Modo 2: Python module
python -m sibilla
# Modo 3: Flask diretto (con hot reload)
python -c "from sibilla.app import create_app; create_app().run(debug=True)"
Produzione (Gunicorn)
# Installa Gunicorn
pip install gunicorn
# Avvia
gunicorn -w 4 -b 0.0.0.0:5000 "sibilla.app:create_app()"
# Con opzioni aggiuntive
gunicorn \
-w 4 \
-b 0.0.0.0:5000 \
--timeout 120 \
--access-logfile /var/log/sibilla/access.log \
--error-logfile /var/log/sibilla/error.log \
"sibilla.app:create_app()"
Deployment in produzione
Checklist pre-deployment
SIBILLA_DEBUG=0(MAI in debug in produzione)SECRET_KEYcambiata con una chiave casuale lungaGOOGLE_API_KEYconfigurata- Reverse proxy (nginx/Caddy) configurato con HTTPS
- Firewall: solo porta 80/443 esposta
- Rate limiting configurato (nginx o middleware)
- Logging configurato
- Health check monitorato
Architettura di produzione consigliata
Internet
│
▼
┌──────────────────┐
│ Nginx / Caddy │ ← Reverse proxy + HTTPS (Let's Encrypt)
│ Porta 80/443 │ + Rate limiting
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Gunicorn │ ← WSGI server
│ 4 workers │ Porta 5000 (internal)
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Sibilla Flask │ ← Application
└────────┬─────────┘
│
┌────┴────┐
▼ ▼
┌────────┐ ┌────────┐
│ Degoog │ │ Gemini │
│ :4444 │ │ API │
└────────┘ └────────┘
Docker Compose
Ecco un esempio di docker-compose.yml per avviare Sibilla + Degoog + SearXNG:
version: "3.8"
services:
sibilla:
build: .
ports:
- "5000:5000"
environment:
- GOOGLE_API_KEY=${GOOGLE_API_KEY}
- SECRET_KEY=${SECRET_KEY:-changeme} # ⚠️ Cambiare in produzione!
- SIBILLA_HOST=0.0.0.0
- SIBILLA_PORT=5000
- SIBILLA_DEBUG=0
- DEGOOG_URL=http://degoog:4444
- SEARXNG_URL=http://searxng:8080
- SIBILLA_DDG_FALLBACK=1
depends_on:
- degoog
- searxng
restart: unless-stopped
degoog:
image: ghcr.io/degoog-org/degoog:latest
ports:
- "4444:4444"
restart: unless-stopped
searxng:
image: searxng/searxng:latest
ports:
- "8080:8080"
environment:
- SEARXNG_BASE_URL=http://localhost:8080/
volumes:
- ./searxng:/etc/searxng:rw
restart: unless-stopped
Avvia con:
docker compose up -d
Reverse Proxy
Nginx
server {
listen 80;
server_name sibilla.tuo-dominio.com;
# Rate limiting
limit_req_zone $binary_remote_addr zone=sibilla:10m rate=10r/m;
limit_req zone=sibilla burst=5 nodelay;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
}
# API endpoint with higher rate limit
location /api/ {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 120s;
}
}
Caddy (più semplice, auto-HTTPS)
sibilla.tuo-dominio.com {
reverse_proxy 127.0.0.1:5000
}
Systemd Service
Crea /etc/systemd/system/sibilla.service:
[Unit]
Description=Sibilla AI Search Engine
After=network.target
[Service]
Type=simple
User=sibilla
Group=sibilla
WorkingDirectory=/opt/sibilla
EnvironmentFile=/opt/sibilla/.env
ExecStart=/opt/sibilla/.venv/bin/gunicorn -w 4 -b 127.0.0.1:5000 "sibilla.app:create_app()"
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Attiva:
sudo systemctl daemon-reload
sudo systemctl enable --now sibilla
sudo systemctl status sibilla
Monitoraggio
Health check endpoint
curl http://localhost:5000/api/health
Monitora con:
- Uptime Kuma — monitoraggio self-hosted
- Healthchecks.io — cron monitoring
- Prometheus + Grafana — metriche avanzate (da aggiungere)
Log
Con Gunicorn:
# Access log
tail -f /var/log/sibilla/access.log
# Error log
tail -f /var/log/sibilla/error.log
Troubleshooting
"GOOGLE_API_KEY is not set"
Il file .env non è stato caricato o manca la variabile:
# Verifica che il file .env esista
ls -la .env
# Verifica il contenuto
cat .env | grep GOOGLE_API_KEY
# Se usi systemd, assicurati che EnvironmentFile punti al percorso corretto
"Connection refused" per Degoog/SearXNG
Il motore di ricerca non è in esecuzione:
# Verifica se Degoog è attivo
curl http://localhost:4444/api/search?q=test
# Verifica se SearXNG è attivo
curl http://localhost:8080/search?q=test&format=json
# Se non rispondono, Sibilla userà automaticamente DuckDuckGo
"502 Bad Gateway" — Tutti i motori down
Verifica che DuckDuckGo fallback sia abilitato:
SIBILLA_DDG_FALLBACK=1
Se anche DuckDuckGo non funziona, Gemini risponderà in modalità "pure LLM" (senza fonti).
Timeout su richieste lente
Aumenta il timeout in Gunicorn:
gunicorn --timeout 180 ...
E nel reverse proxy:
proxy_read_timeout 180s;