- Contesto Aziendale
- Obiettivi del Progetto
- Panoramica del Sistema
- Architettura
- Struttura del Progetto
- Prerequisiti
- Installazione e Configurazione
- Utilizzo
- Monitoraggio
- CI/CD con Jenkins
- Deploy su Kubernetes
- Sicurezza
- Troubleshooting
- Repository GitHub
- Contribuire
Una piattaforma di e-commerce riceve migliaia di recensioni sui prodotti ogni giorno. Analizzare il sentimento di queste recensioni (positivo, negativo, neutro) è cruciale per:
- Migliorare i prodotti: Identificare rapidamente problemi segnalati dai clienti
- Ottimizzare il servizio clienti: Prioritarizzare le recensioni negative per risposte immediate
- Decisioni basate sui dati: Utilizzare insight quantitativi per guidare strategie di prodotto
- Scalabilità: Gestire volumi crescenti di recensioni senza intervento manuale
Questo progetto implementa un sistema automatizzato per il deploy e il monitoraggio di un modello di Sentiment Analysis, garantendo scalabilità, affidabilità e monitoraggio proattivo.
- Implementare un modello di Sentiment Analysis utilizzando un framework di Machine Learning (scikit-learn)
- Creare un pipeline CI/CD con Jenkins per automatizzare il deploy del modello
- Configurare un'infrastruttura di monitoraggio con Prometheus e Grafana per metriche in tempo reale
- Documentare e gestire il progetto su repository GitHub
Il sistema è composto da:
- API REST Flask: Servizio web che espone il modello di sentiment analysis
- Prometheus: Sistema di monitoraggio e raccolta metriche
- Grafana: Dashboard interattive per visualizzazione metriche
- Jenkins: Pipeline CI/CD per automazione deploy
- Docker & Kubernetes: Containerizzazione e orchestrazione
Recensione → API Flask → Modello ML → Risposta JSON
↓
Metriche Prometheus
↓
Dashboard Grafana
┌─────────────────────────────────────────────────────────┐
│ Docker Network │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Flask API │───▶│ Prometheus │ │
│ │ :5000 │ │ :9090 │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌──────────────┐ │
│ └───────────▶│ Grafana │ │
│ │ :3000 │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
Il sistema può essere deployato su Kubernetes utilizzando i manifest nella directory k8s/, che includono:
- Namespace: Isolamento logico delle risorse
- Deployment: Gestione dei pod per API, Prometheus e Grafana
- Service: Esposizione dei servizi
- ConfigMap: Configurazioni Prometheus e Grafana
- Secret: Gestione sicura di password e token
SentimentAnalysis/
│
├── api/ # API Flask
│ ├── app.py # Applicazione principale Flask
│ ├── Dockerfile # Immagine Docker per l'API
│ ├── requirements.txt # Dipendenze Python
│ ├── templates/
│ │ └── index.html # Pagina web di test
│ └── tests/
│ └── test_app.py # Test unitari
│
├── monitoring/ # Configurazioni monitoraggio
│ ├── prometheus.yml # Configurazione Prometheus
│ ├── alerts.yml # Regole di alerting
│ └── grafana/
│ ├── provisioning/
│ │ ├── datasources/
│ │ │ └── datasource.yml # Datasource Prometheus
│ │ └── dashboards/
│ │ └── dashboard.yml # Configurazione dashboard
│ └── dashboards/
│ └── sentiment-overview.json # Dashboard principale
│
├── jenkins/ # Pipeline CI/CD
│ └── Jenkinsfile # Definizione pipeline Jenkins
│
├── k8s/ # Manifest Kubernetes
│ └── sentiment-stack.yaml # Stack completo Kubernetes
│
├── docker-compose.yml # Orchestrazione servizi locali
├── env.example # Template variabili ambiente
├── .gitignore # File esclusi da Git
└── README.md # Questa documentazione
- Docker (versione 20.10+)
- Docker Compose (versione 2.0+)
- Python 3.9+ (opzionale, solo per test locali)
- Git (per clonare il repository)
- kubectl configurato e connesso a un cluster Kubernetes
- Cluster Kubernetes funzionante (minikube, kind, o cloud provider)
- Jenkins installato e configurato
- Plugin Docker installato su Jenkins
- Accesso a Docker da Jenkins
git clone https://github.com/TUO-USERNAME/SentimentAnalysis.git
cd SentimentAnalysisCrea un file .env basato su env.example:
cp env.example .envModifica .env con i tuoi valori:
# Password amministratore Grafana
GF_SECURITY_ADMIN_PASSWORD=tua_password_sicura
# Token Bearer per autenticazione API (opzionale)
API_TOKEN=il_tuo_token_segreto
# URL del modello (default: repository pubblico)
MODEL_URL=https://github.com/Profession-AI/progetti-devops/raw/refs/heads/main/Deploy%20e%20monitoraggio%20di%20un%20modello%20di%20sentiment%20analysis%20per%20recensioni/sentimentanalysismodel.pkl.env è escluso da Git per sicurezza. Non committarlo mai!
docker-compose up -d --buildQuesto comando:
- Costruisce l'immagine Docker dell'API
- Scarica le immagini di Prometheus e Grafana
- Avvia tutti i servizi in background
docker-compose psDovresti vedere tre servizi in esecuzione:
sentiment-apiprometheusgrafana
# Log di tutti i servizi
docker-compose logs -f
# Log solo dell'API
docker-compose logs -f sentiment-apiAccesso: http://localhost:5000
Interfaccia web semplice per testare l'API.
Endpoint principale per analizzare il sentiment di una recensione.
Richiesta:
curl -X POST http://localhost:5000/predict \
-H "Content-Type: application/json" \
-d '{"review": "This product is amazing! I love it."}'Con Autenticazione (se API_TOKEN è configurato):
curl -X POST http://localhost:5000/predict \
-H "Content-Type: application/json" \
-H "Authorization: Bearer il_tuo_token_segreto" \
-d '{"review": "This product is amazing! I love it."}'Risposta:
{
"sentiment": "positive",
"confidence": 0.95
}Possibili valori di sentiment:
"positive": Sentimento positivo"negative": Sentimento negativo"neutral": Sentimento neutro (se supportato dal modello)
Codici di Risposta:
200 OK: Predizione riuscita400 Bad Request: Richiesta malformata (manca camporeview)401 Unauthorized: Token mancante o non valido (se autenticazione attiva)500 Internal Server Error: Errore durante la predizione
Verifica lo stato dell'API.
curl http://localhost:5000/healthRisposta:
{
"status": "ok"
}Espone le metriche in formato Prometheus.
curl http://localhost:5000/metricsMetriche Esposte:
request_count: Contatore delle richieste per metodo, endpoint e status HTTPrequest_latency_seconds: Istogramma della latenza delle richiesteprediction_errors_total: Contatore degli errori di predizioneauth_failures_total: Contatore dei fallimenti di autenticazione
import requests
# Configurazione
API_URL = "http://localhost:5000"
API_TOKEN = "il_tuo_token_segreto" # Opzionale
# Headers
headers = {
"Content-Type": "application/json"
}
if API_TOKEN:
headers["Authorization"] = f"Bearer {API_TOKEN}"
# Analisi sentiment
response = requests.post(
f"{API_URL}/predict",
json={"review": "This product exceeded my expectations!"},
headers=headers
)
result = response.json()
print(f"Sentiment: {result['sentiment']}")
print(f"Confidence: {result['confidence']:.2%}")const axios = require('axios');
const API_URL = 'http://localhost:5000';
const API_TOKEN = 'il_tuo_token_segreto'; // Opzionale
const headers = {
'Content-Type': 'application/json'
};
if (API_TOKEN) {
headers['Authorization'] = `Bearer ${API_TOKEN}`;
}
axios.post(`${API_URL}/predict`,
{ review: 'This product exceeded my expectations!' },
{ headers }
)
.then(response => {
console.log(`Sentiment: ${response.data.sentiment}`);
console.log(`Confidence: ${response.data.confidence * 100}%`);
})
.catch(error => {
console.error('Error:', error.response?.data || error.message);
});Accesso: http://localhost:9090
Prometheus raccoglie automaticamente le metriche dall'API ogni 15 secondi.
Numero totale di richieste:
sum(rate(request_count[5m]))
Latenza p95:
histogram_quantile(0.95, sum(rate(request_latency_seconds_bucket[5m])) by (le))
Tasso di errori:
rate(prediction_errors_total[5m])
Throughput per endpoint:
sum(rate(request_count[5m])) by (endpoint)
Accesso: http://localhost:3000
Credenziali:
- Username:
admin - Password: Valore di
GF_SECURITY_ADMIN_PASSWORDnel file.env
Il sistema include una dashboard preconfigurata "Sentiment API - Overview" che mostra:
- Richieste Totali: Grafico a linea del numero di richieste nel tempo
- Errori di Predizione: Contatore degli errori
- Fallimenti Autenticazione: Contatore dei fallimenti auth
- Latenza p95: Istogramma della latenza percentile 95
- Throughput: Richieste al secondo per endpoint
La dashboard viene caricata automaticamente al primo avvio di Grafana grazie al provisioning.
Prometheus include regole di alerting configurate in monitoring/alerts.yml:
- HighErrorRate: Si attiva quando ci sono più di 5 errori di predizione in 5 minuti
- HighLatencyP95: Si attiva quando la latenza p95 supera 1 secondo per più di 5 minuti
Gli alert possono essere visualizzati in Prometheus (http://localhost:9090/alerts) e configurati per inviare notifiche via email, Slack, ecc.
-
Crea una nuova Pipeline:
- Vai su Jenkins → New Item
- Seleziona "Pipeline"
- Nome:
sentiment-analysis-pipeline
-
Configura il Repository:
- Pipeline definition: "Pipeline script from SCM"
- SCM: Git
- Repository URL: URL del tuo repository GitHub/GitLab
- Script Path:
jenkins/Jenkinsfile
-
Configura Credenziali (se necessario):
- Se il repository è privato, aggiungi credenziali Git
- Se usi Kubernetes, configura credenziali
kubectl
Il Jenkinsfile definisce una pipeline con i seguenti stage:
- Checkout: Scarica il codice dal repository
- Build: Costruisce l'immagine Docker dell'API
- Test: Esegue i test unitari con
pytest - Deploy:
- Deploy con Docker Compose (default)
- Deploy su Kubernetes (se
APPLY_K8S=true)
La pipeline si attiva automaticamente su:
- Push su branch
main - Pull Request (opzionale, configurabile)
Puoi configurare parametri opzionali:
APPLY_K8S: Setrue, applica i manifest Kubernetes invece di Docker Compose
La pipeline include notifiche di successo/fallimento nella sezione post.
- Cluster Kubernetes funzionante
kubectlconfigurato e connesso al cluster- Accesso per creare namespace, deployment, service, configmap e secret
kubectl apply -f k8s/sentiment-stack.yamlQuesto comando crea:
- Namespace
sentiment-analysis - Secret con password Grafana e token API
- ConfigMap per Prometheus (configurazione + alerting)
- ConfigMap per provisioning Grafana
- Deployment e Service per API, Prometheus e Grafana
# Verifica namespace
kubectl get namespace sentiment-analysis
# Verifica pod
kubectl get pods -n sentiment-analysis
# Verifica servizi
kubectl get svc -n sentiment-analysis
# Log dell'API
kubectl logs -n sentiment-analysis -l app=sentiment-api -f# API
kubectl port-forward -n sentiment-analysis svc/sentiment-api 5000:5000
# Prometheus
kubectl port-forward -n sentiment-analysis svc/prometheus 9090:9090
# Grafana
kubectl port-forward -n sentiment-analysis svc/grafana 3000:3000Per esporre i servizi pubblicamente, configura un Ingress controller e aggiungi le regole appropriate.
Dopo modifiche al codice:
# Ricostruisci l'immagine Docker
docker build -t sentiment-analysis-api:latest ./api
# Carica nel cluster (per minikube)
minikube image load sentiment-analysis-api:latest
# Riavvia i pod
kubectl rollout restart deployment/sentiment-api -n sentiment-analysisL'API supporta autenticazione opzionale tramite token Bearer:
- Imposta
API_TOKENnel file.env - Tutte le richieste (tranne
/,/health,/metrics) richiedono l'header:Authorization: Bearer <token>
- Non hardcodare la password nel
docker-compose.yml - Utilizza sempre variabili ambiente tramite
.env - Cambia la password di default dopo il primo accesso
- File
.env: Mai committare file.envnel repository - Secret Kubernetes: Utilizza Secret invece di ConfigMap per dati sensibili
- HTTPS: In produzione, configura HTTPS/TLS per tutti i servizi
- Network Policies: In Kubernetes, configura Network Policies per limitare il traffico
- Resource Limits: Imposta limiti di CPU/memoria per i container
Sintomi: curl http://localhost:5000/health restituisce errore di connessione
Soluzioni:
- Verifica che il container sia in esecuzione:
docker-compose ps - Controlla i log:
docker-compose logs sentiment-api - Verifica che la porta 5000 non sia già in uso:
netstat -an | findstr 5000
Sintomi: L'API funziona ma usa il fallback TextBlob
Soluzioni:
- Verifica che
MODEL_URLsia corretto nel.env - Controlla i log per errori di download:
docker-compose logs sentiment-api - Verifica la connettività di rete dal container:
docker-compose exec sentiment-api ping github.com
Sintomi: Dashboard vuota o "No data"
Soluzioni:
- Verifica che Prometheus stia raccogliendo metriche:
http://localhost:9090/targets - Controlla che il datasource Prometheus sia configurato: Grafana → Configuration → Data Sources
- Verifica che l'API esponga metriche:
curl http://localhost:5000/metrics
Sintomi: Nessuna metrica in Prometheus
Soluzioni:
- Verifica la configurazione:
docker-compose exec prometheus cat /etc/prometheus/prometheus.yml - Controlla i target:
http://localhost:9090/targets(dovrebbe mostraresentiment-api:5000come UP) - Verifica la connettività di rete:
docker-compose exec prometheus ping sentiment-api
Sintomi: Build o test falliscono
Soluzioni:
- Verifica che Docker sia accessibile da Jenkins
- Controlla i log della pipeline in Jenkins
- Verifica che le dipendenze Python siano installate per i test
- Assicurati che il repository sia accessibile da Jenkins
-
Crea un nuovo repository su GitHub:
- Vai su https://github.com/new
- Nome:
SentimentAnalysis(o altro) - Non inizializzare con README, .gitignore o licenza (già presenti)
-
Aggiungi il remote e pubblica:
git remote add origin https://github.com/TUO-USERNAME/SentimentAnalysis.git git branch -M main git push -u origin main
-
Configura GitHub Actions (opzionale):
- Crea
.github/workflows/ci.ymlper CI automatico - Integra con Jenkins per CD
- Crea
Il repository include:
- ✅ Codice sorgente completo dell'API Flask
- ✅ Configurazioni Docker e Docker Compose
- ✅ Manifest Kubernetes completi
- ✅ Pipeline CI/CD Jenkins
- ✅ Configurazioni Prometheus e Grafana
- ✅ Dashboard e alerting preconfigurati
- ✅ Test automatizzati
- ✅ Documentazione completa
Puoi aggiungere badge al README per mostrare lo stato del progetto:

- Fork il repository
- Crea un branch per la tua feature (
git checkout -b feature/AmazingFeature) - Commit le modifiche (
git commit -m 'Add some AmazingFeature') - Push al branch (
git push origin feature/AmazingFeature) - Apri una Pull Request
- Segui le convenzioni PEP 8 per Python
- Aggiungi test per nuove funzionalità
- Aggiorna la documentazione se necessario
- Assicurati che tutti i test passino prima di fare commit
Se trovi un bug, apri una Issue su GitHub includendo:
- Descrizione del problema
- Passi per riprodurre
- Log rilevanti
- Ambiente (OS, versione Docker, ecc.)
Questo progetto è rilasciato sotto licenza MIT. Vedi il file LICENSE per dettagli.
- Tu - Sviluppo iniziale - TuoGitHub
- Modello di sentiment analysis fornito da Profession-AI
- Comunità open source per gli strumenti utilizzati (Flask, Prometheus, Grafana, Jenkins)
Per domande o supporto:
- Apri una Issue su GitHub
- Consulta la documentazione
- Controlla la sezione Troubleshooting
Ultimo aggiornamento: Gennaio 2025