Local (Dev)
Objectif & portée¶
Horodatage¶
-
Tous les timestamps JSON sont au format ISO 8601 UTC (suffixe
Z). L'affichage local (UTC+1) est une option UI uniquement. -
Exécuter SalamBot en local pour développement, tests et démos.
- Stack par défaut: Docker Compose; notes K8s local (kind/microk8s) optionnelles.
- Inclure observabilité minimale, persistance et données d'exemple.
Architecture locale (aperçu)¶
| Service | Port | Rôle |
|---|---|---|
| gateway | 8080 | API/ingress |
| orchestrateur | 8081 | coordination |
| nlu | 8082 | NLU/LLM wrapper |
| rag | 8083 | retrieval |
| postgres | 5432 | métadonnées |
| redis | 6379 | cache/queues |
| qdrant | 6333 | Vector DB |
| minio | 9000/9001 | objets (KB/documents) + console |
| prometheus | 9090 | métriques |
| grafana | 3001 | dashboards |
| otel-collector | 4317/4318 | OTLP gRPC/HTTP → export observabilité |
| tempo | 3200 | traces distribuées |
Prérequis¶
⚠️ Sécurité dev vs prod
Les identifiants par défaut (ex. Grafanaadmin/admin, MinIOadmin/admin) et services non chiffrés sont réservés au local. En prod/on-prem : changer tous les mots de passe, activer TLS (ingress + MinIO console), restreindre l'accès à Grafana/Prometheus (IP/VPN/SSO) et désactiver les consoles publiques inutiles.
- Docker ≥ 24 et Compose v2
- Make (optionnel), Git
- CPU 4+, RAM 8 Go+, 10 Go disque libres
- Accès aux images et secrets requis (dev)
URL rapides d'observabilité¶
Interfaces principales¶
| Service | URL | Login par défaut | Description |
|---|---|---|---|
| Prometheus | http://localhost:9090 | - | Métriques et requêtes PromQL |
| Grafana | http://localhost:3000 | admin/admin | Dashboards et visualisations |
| Tempo | http://localhost:3200 | - | API traces (via Grafana) |
Pages utiles¶
- Prometheus Targets : http://localhost:9090/targets
- Prometheus Graph : http://localhost:9090/graph
- Prometheus Alerts : http://localhost:9090/alerts
- Grafana Explore : http://localhost:3000/explore
Requêtes PromQL de base¶
# Taux de requêtes HTTP par seconde
sum(rate(http_requests_total[1m]))
# Latence P95 par route
histogram_quantile(0.95, sum(rate(http_server_duration_ms_bucket[5m])) by (le,route))
# Erreurs RAG
sum(rate(rag_search_errors_total[5m]))
# Santé des services
up{job="otel-collector"}
Vérifications rapides¶
# Métriques du collector
curl -s http://localhost:8889/metrics | head
# Targets Prometheus
curl -s http://localhost:9090/api/v1/targets | jq '.data.activeTargets[] | {job, instance, health, lastScrape}'
# Test requête PromQL
curl -s "http://localhost:9090/api/v1/query?query=up" | jq '.data.result[] | {metric, value}'
Démarrage des services¶
- Si votre
docker-compose.ymlutilise des profiles, activez l'observabilité (inclutotel-collector) :
docker compose --profile observability up -d
Mise en route rapide¶
- Cloner le repo et se placer à la racine.
- Copier
.env.examplevers.envet ajuster. - Lancer
docker compose up -d(oumake up). - Vérifier
docker compose pspuis/health. - Ouvrir Grafana : http://localhost:3001
git clone <repo>
cd salambot
cp .env.example .env
docker compose up -d
curl -f http://localhost:8080/health
Configuration .env (extraits)¶
- Variables clés: TENANT=demo, OPENAI_API_KEY=..., RAG_PROVIDER=qdrant.
- Endpoints internes pointent sur localhost et ports ci-dessus.
- Sécurité: valeurs dev uniquement, ne pas committer.
TENANT=demo
OPENAI_API_KEY=sk-...
POSTGRES_URL=postgres://salambot:salambot@postgres:5432/salambot
REDIS_URL=redis://redis:6379
QDRANT_URL=http://qdrant:6333
MINIO_ENDPOINT=http://minio:9000
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=adminadmin
MINIO_CONSOLE=http://localhost:9001
# Export OTLP vers l'OTel Collector (HTTP 4318)
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
Données & persistance¶
- Volumes Docker pour Postgres, MinIO, Qdrant.
- Seed de données démo (tenant, KB) via scripts.
- Commandes pour reset sélectif (DB/KV/Vector).
Initialisation MinIO (avant seed)¶
docker compose exec minio mc alias set local http://minio:9000 \
"$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"
docker compose exec minio mc mb -p local/salambot-kb || true
docker compose exec minio mc policy set public local/salambot-kb
docker compose exec orchestrateur python -m salambot.jobs.seed_kb --tenant demo --incremental
# Reset Qdrant (attention: destructif)
curl -X DELETE http://localhost:6333/collections/salambot-kb
Observabilité locale¶
Services d'observabilité¶
| Service | Port | URL | Rôle |
|---|---|---|---|
| Prometheus | 9090 | http://localhost:9090 | Métriques et alertes |
| Grafana | 3001 | http://localhost:3001 | Dashboards (admin/admin) |
| OpenTelemetry | 4317 | http://localhost:4317 | OTLP gRPC (traces/métriques) |
| OpenTelemetry | 4318 | http://localhost:4318 | OTLP HTTP (traces/métriques) |
| Collector Metrics | 8889 | http://localhost:8889/metrics | Métriques Prometheus du Collector |
| Tempo | 3200 | http://localhost:3200 | Backend traces (Jaeger-compatible) |
Dashboards Grafana disponibles¶
- API Overview (
salambot-api-overview) : - Taux de requêtes API (RPS)
- Latence API P50/P95/P99 avec exemplars
- Taux d'erreur 4xx/5xx
-
Disponibilité SLO (99.9% target)
-
RAG Overview (
salambot-rag-overview) : - Recherches RAG vers Qdrant (RPS)
- Latence recherche P50/P95/P99
- Taux d'erreur RAG
-
Statut Qdrant et fiabilité
-
OpenTelemetry Infrastructure (
salambot-otel-infra) : - Statut Collector/Prometheus/Grafana
- Débit spans et métriques
- Taux d'erreur export
- Utilisation mémoire
Exemples PromQL utiles¶
# Latence P95 API Gateway
histogram_quantile(0.95, sum(rate(http_request_duration_ms_bucket{job="salambot-gateway"}[5m])) by (le, route))
# Taux d'erreur 5xx sur 5 minutes
sum(rate(http_requests_total{job="salambot-gateway", code=~"5.."}[5m])) / sum(rate(http_requests_total{job="salambot-gateway"}[5m])) * 100
# Recherches RAG par seconde
sum(rate(rag_search_total{db_system="qdrant"}[5m])) by (peer_service)
# Latence recherche Qdrant P99
histogram_quantile(0.99, sum(rate(rag_search_latency_ms_bucket{db_system="qdrant"}[5m])) by (le))
# Disponibilité services SalamBot
avg_over_time(up{job=~"salambot-.*"}[5m])
Alertes configurées¶
- Latence API : P95 > 2s ou P99 > 5s pendant 5 minutes
- Taux d'erreur : 5xx > 5% ou erreurs RAG > 2% pendant 5 minutes
- Disponibilité : Qdrant down ou services SalamBot indisponibles
Accès rapide¶
# macOS
open http://localhost:9090 || true # Prometheus
open http://localhost:3001 || true # Grafana
# Linux
xdg-open http://localhost:9090 || true
xdg-open http://localhost:3001 || true
# Logs
docker compose logs -f gateway orchestrateur nlu rag
# Métriques directes
curl http://localhost:8889/metrics # Collector
curl http://localhost:8080/metrics # Gateway
curl http://localhost:8083/metrics # RAG
Tests fumée¶
- Vérifier santé services (health checks).
- Générer une réponse et vérifier TTFB.
- Tester recherche RAG.
TOKEN="dev-token" # adapter si auth activée
TENANT="demo"
# Health
curl -H "Authorization: Bearer $TOKEN" \
-H "X-SalamBot-Tenant: $TENANT" \
http://localhost:8080/health
# Génération (endpoint canonique)
curl -X POST http://localhost:8080/v1/generate/reply \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $TOKEN" \
-H "X-SalamBot-Tenant: $TENANT" \
-d '{
"schema_version":"1.0",
"tenant":"demo",
"channel":"webchat",
"message_id":"msg_smoke",
"correlation_id":"corr_smoke",
"timestamp":"2025-08-14T10:00:00Z",
"locale":"fr-MA",
"data":{"prompt":"Bonjour","context":[]}
}'
# Recherche RAG (endpoint canonique)
curl -X POST http://localhost:8080/v1/search/query \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $TOKEN" \
-H "X-SalamBot-Tenant: $TENANT" \
-d '{"query":"test","tenant":"demo","top_k":3}'
# Note: si l'environnement DEV désactive l'auth, retirer les en-têtes
# Authorization/X-SalamBot-Tenant et documenter clairement cette exception.
Tests et validation¶
Tests de bout en bout¶
# Tests Gateway (smoke tests)
cd services/gateway
pnpm test
# Tests RAG (endpoints + métriques)
cd services/rag
pnpm test
# Tests NLU
cd services/nlu
pnpm test
# Tests Orchestrator
cd services/orchestrator
pnpm test
# Tests script seed-kb (nécessite Qdrant actif)
npx vitest run scripts/tests/seed-kb.test.ts
Validation des endpoints¶
# Health checks
curl http://localhost:8080/health
curl http://localhost:8081/health
curl http://localhost:8082/health
curl http://localhost:8083/health
# Test search endpoint
curl -X POST http://localhost:8080/v1/search/query \
-H "Content-Type: application/json" \
-H "Authorization: Bearer test-token" \
-H "X-SalamBot-Tenant: demo" \
-d '{"query": "comment utiliser SalamBot", "top_k": 5}'
# Test generate endpoint
curl -X POST http://localhost:8080/v1/generate/reply \
-H "Content-Type: application/json" \
-H "Authorization: Bearer test-token" \
-H "X-SalamBot-Tenant: demo" \
-d '{"query": "Bonjour, comment ça va?"}'
# Métriques Prometheus
curl http://localhost:8083/metrics
Note API : webhooks & signatures HMAC centralisés dans
API/reference.md#webhooks.
Troubleshooting¶
- Conflits de ports: modifier mapping dans compose.
- Mémoire insuffisante: réduire réplicas, désactiver services non utilisés.
- Démarrage lent DB/Vector: relancer
ragaprèsqdrantprêt. - Erreur de secrets: vérifier
.envet variables exportées. - Certificats/SSL locaux: utiliser HTTP interne en dev.
Démarrage ordonné (healthchecks)¶
# extrait docker-compose.yml
services:
qdrant:
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:6333/collections']
interval: 10s
timeout: 3s
retries: 12
postgres:
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U salambot -d salambot']
interval: 10s
timeout: 3s
retries: 12
redis:
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 10s
timeout: 3s
retries: 12
rag:
depends_on:
qdrant:
condition: service_healthy
orchestrateur:
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
Endpoints canoniques¶
- Utiliser uniquement :
/v1/generate/replyet/v1/search/query. - Supprimer toute référence à des variantes (
/generate/reply,/v1/chat/completions, etc.).
Cohérence API: utilisez les chemins canoniques décrits dans
API/reference.md. Si plusieurs variantes existent (/v1/generate/reply,
/v1/chat/completions), indiquez celle supportée localement.
Nettoyage¶
- Arrêt:
docker compose down - Purge volumes (destructif):
docker compose down -v - Suppression images optionnelle:
docker image prune
Notes K8s local (optionnel)¶
- Déploiement rapide avec kind:
kind create cluster. - Utiliser manifests allégés + NodePort.
- Observabilité via kube-prometheus-stack (profil dev).
Références croisées¶
- Runbooks : procédures d'incident et escalade
- IAM : contrôles d'accès et authentification
- PII & Privacy : gestion des données personnelles
- Audit & Logging : journalisation et traçabilité
- SLO & SLA : métriques de disponibilité
Horodatage des exemples : UTC
Zuniquement (affichage local optionnel).