# Configuration du Système - 4NK_IA Notarial ## ⚙️ Vue d'ensemble de la Configuration Ce document détaille toutes les configurations nécessaires pour déployer et faire fonctionner le système notarial 4NK_IA. ## 🔧 Fichiers de Configuration ### **Structure des Fichiers** ``` 4NK_IA/ ├── infra/ │ ├── .env # Variables d'environnement │ ├── .env.example # Template de configuration │ ├── docker-compose.yml # Services de production │ └── docker-compose.dev.yml # Services de développement ├── services/ │ ├── host_api/ │ │ ├── requirements.txt # Dépendances Python │ │ └── app.py # Configuration FastAPI │ └── worker/ │ └── requirements.txt # Dépendances Worker ├── ops/ │ ├── nginx.conf # Configuration Nginx │ └── grafana/ # Dashboards Grafana └── Makefile # Commandes de gestion ``` ## 🌍 Variables d'Environnement ### **Fichier `.env` Principal** ```bash # Configuration du projet PROJECT_NAME=notariat DOMAIN=localhost TZ=Europe/Paris # Base de données PostgreSQL POSTGRES_USER=notariat POSTGRES_PASSWORD=notariat_pwd POSTGRES_DB=notariat DATABASE_URL=postgresql+psycopg://notariat:notariat_pwd@postgres:5432/notariat # Redis (Cache et Queue) REDIS_URL=redis://redis:6379/0 REDIS_PASSWORD= # MinIO (Stockage objet) MINIO_ROOT_USER=minio MINIO_ROOT_PASSWORD=minio_pwd MINIO_BUCKET=ingest MINIO_ENDPOINT=minio:9000 # Ollama (LLM local) OLLAMA_BASE_URL=http://ollama:11434 OLLAMA_MODEL=llama3:8b # AnythingLLM (RAG) ANYLLM_BASE_URL=http://anythingsqlite:3001 ANYLLM_API_KEY=sk-anythingllm ANYLLM_WORKSPACE_NORMES=normes ANYLLM_WORKSPACE_TRAMES=trames ANYLLM_WORKSPACE_ACTES=actes # Neo4j (Graphe) NEO4J_AUTH=neo4j/neo4j_pwd NEO4J_URI=bolt://neo4j:7687 # OpenSearch (Recherche) OPENSEARCH_URL=http://opensearch:9200 OPENSEARCH_PASSWORD=opensearch_pwd # Traefik (Load Balancer) TRAEFIK_DASHBOARD=true TRAEFIK_API=true TRAEFIK_ACME_EMAIL=ops@4nkweb.com # Sécurité JWT_SECRET_KEY=your-super-secret-jwt-key-change-in-production JWT_ALGORITHM=HS256 JWT_EXPIRATION=3600 # Monitoring PROMETHEUS_URL=http://prometheus:9090 GRAFANA_URL=http://grafana:3000 ``` ### **Variables par Environnement** #### **Développement** ```bash # .env.dev ENVIRONMENT=development DEBUG=true LOG_LEVEL=DEBUG DATABASE_URL=postgresql+psycopg://notariat:notariat_pwd@localhost:5432/notariat_dev REDIS_URL=redis://localhost:6379/0 ``` #### **Production** ```bash # .env.prod ENVIRONMENT=production DEBUG=false LOG_LEVEL=INFO DATABASE_URL=postgresql+psycopg://notariat:${POSTGRES_PASSWORD}@postgres:5432/notariat REDIS_URL=redis://redis:6379/0 ``` ## 🐳 Configuration Docker ### **Docker Compose Principal** ```yaml # infra/docker-compose.yml version: '3.8' x-env: &default-env TZ: ${TZ} PUID: "1000" PGID: "1000" services: postgres: image: postgres:16 environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - pgdata:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 30s timeout: 10s retries: 3 redis: image: redis:7 command: ["redis-server", "--appendonly", "yes"] volumes: - redis:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 3 minio: image: minio/minio:latest command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - minio:/data ports: - "9000:9000" - "9001:9001" restart: unless-stopped ollama: image: ollama/ollama:latest volumes: - ollama:/root/.ollama ports: - "11434:11434" restart: unless-stopped environment: - OLLAMA_HOST=0.0.0.0 anythingsqlite: image: kevincharm/anythingllm:latest environment: - DISABLE_AUTH=true depends_on: - ollama ports: - "3001:3001" restart: unless-stopped neo4j: image: neo4j:5.23 environment: - NEO4J_AUTH=${NEO4J_AUTH} - NEO4J_PLUGINS=["apoc"] volumes: - neo4j:/data ports: - "7474:7474" - "7687:7687" restart: unless-stopped opensearch: image: opensearchproject/opensearch:2.11.0 environment: - discovery.type=single-node - "OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_PASSWORD}" volumes: - opensearch:/usr/share/opensearch/data ports: - "9200:9200" restart: unless-stopped traefik: image: traefik:v3.0 command: - "--api.dashboard=true" - "--providers.docker=true" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.letsencrypt.acme.email=${TRAEFIK_ACME_EMAIL}" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - letsencrypt:/letsencrypt restart: unless-stopped prometheus: image: prom/prometheus:latest volumes: - ./ops/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus:/prometheus ports: - "9090:9090" restart: unless-stopped grafana: image: grafana/grafana:latest environment: - GF_SECURITY_ADMIN_PASSWORD=admin volumes: - grafana:/var/lib/grafana - ./ops/grafana/provisioning:/etc/grafana/provisioning ports: - "3000:3000" restart: unless-stopped volumes: pgdata: redis: minio: ollama: neo4j: opensearch: letsencrypt: prometheus: grafana: networks: default: driver: bridge ``` ### **Configuration de Développement** ```yaml # infra/docker-compose.dev.yml version: '3.8' services: postgres: image: postgres:16 environment: POSTGRES_USER: notariat POSTGRES_PASSWORD: notariat_pwd POSTGRES_DB: notariat_dev ports: - "5432:5432" volumes: - ./dev-data/postgres:/var/lib/postgresql/data redis: image: redis:7 ports: - "6379:6379" volumes: - ./dev-data/redis:/data minio: image: minio/minio:latest command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minio MINIO_ROOT_PASSWORD: minio_pwd ports: - "9000:9000" - "9001:9001" volumes: - ./dev-data/minio:/data ``` ## 🐍 Configuration Python ### **Configuration FastAPI** ```python # services/host_api/config.py from pydantic import BaseSettings from typing import Optional class Settings(BaseSettings): # Application app_name: str = "API Notariale" app_version: str = "1.0.0" debug: bool = False # Database database_url: str = "postgresql+psycopg://notariat:notariat_pwd@localhost:5432/notariat" # Redis redis_url: str = "redis://localhost:6379/0" # MinIO minio_endpoint: str = "localhost:9000" minio_access_key: str = "minio" minio_secret_key: str = "minio_pwd" minio_bucket: str = "ingest" # Ollama ollama_base_url: str = "http://localhost:11434" ollama_model: str = "llama3:8b" # Security jwt_secret_key: str = "your-secret-key" jwt_algorithm: str = "HS256" jwt_expiration: int = 3600 # External APIs cadastre_api_key: Optional[str] = None georisques_api_key: Optional[str] = None bodacc_api_key: Optional[str] = None class Config: env_file = ".env" case_sensitive = False settings = Settings() ``` ### **Configuration Celery** ```python # services/worker/config.py from celery import Celery import os # Configuration Celery broker_url = os.getenv("REDIS_URL", "redis://localhost:6379/0") result_backend = os.getenv("REDIS_URL", "redis://localhost:6379/0") app = Celery('worker', broker=broker_url, backend=result_backend) # Configuration des tâches app.conf.update( task_serializer='json', accept_content=['json'], result_serializer='json', timezone='Europe/Paris', enable_utc=True, task_track_started=True, task_time_limit=30 * 60, # 30 minutes task_soft_time_limit=25 * 60, # 25 minutes worker_prefetch_multiplier=1, worker_max_tasks_per_child=1000, task_routes={ 'pipeline.process_document': {'queue': 'processing'}, 'pipeline.health_check': {'queue': 'monitoring'}, 'pipeline.cleanup': {'queue': 'cleanup'}, } ) ``` ## 🔧 Configuration des Services ### **Nginx Configuration** ```nginx # ops/nginx.conf upstream api_backend { server api:8000; } upstream web_backend { server web:8081; } server { listen 80; server_name localhost; # API location /api/ { proxy_pass http://api_backend; 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; } # Web UI location / { proxy_pass http://web_backend; 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; } # Static files location /static/ { alias /app/static/; expires 1y; add_header Cache-Control "public, immutable"; } } ``` ### **Prometheus Configuration** ```yaml # ops/prometheus/prometheus.yml global: scrape_interval: 15s evaluation_interval: 15s rule_files: - "rules/*.yml" scrape_configs: - job_name: 'api' static_configs: - targets: ['api:8000'] metrics_path: '/metrics' scrape_interval: 5s - job_name: 'worker' static_configs: - targets: ['worker:5555'] metrics_path: '/metrics' scrape_interval: 5s - job_name: 'postgres' static_configs: - targets: ['postgres:5432'] scrape_interval: 30s - job_name: 'redis' static_configs: - targets: ['redis:6379'] scrape_interval: 30s - job_name: 'minio' static_configs: - targets: ['minio:9000'] scrape_interval: 30s - job_name: 'ollama' static_configs: - targets: ['ollama:11434'] scrape_interval: 30s - job_name: 'neo4j' static_configs: - targets: ['neo4j:7474'] scrape_interval: 30s - job_name: 'opensearch' static_configs: - targets: ['opensearch:9200'] scrape_interval: 30s ``` ### **Grafana Dashboards** ```json { "dashboard": { "title": "4NK_IA Notarial System", "panels": [ { "title": "API Requests", "type": "graph", "targets": [ { "expr": "rate(http_requests_total[5m])", "legendFormat": "{{method}} {{endpoint}}" } ] }, { "title": "Document Processing", "type": "stat", "targets": [ { "expr": "documents_processed_total", "legendFormat": "Documents Processed" } ] }, { "title": "System Health", "type": "table", "targets": [ { "expr": "up", "legendFormat": "{{instance}}" } ] } ] } } ``` ## 🔐 Configuration de Sécurité ### **Certificats SSL** ```bash # Génération des certificats Let's Encrypt certbot certonly --webroot -w /var/www/html -d yourdomain.com # Configuration Traefik pour SSL traefik: command: - "--certificatesresolvers.letsencrypt.acme.email=ops@4nkweb.com" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" ``` ### **Firewall Configuration** ```bash # UFW Configuration ufw default deny incoming ufw default allow outgoing ufw allow ssh ufw allow 80/tcp ufw allow 443/tcp ufw allow 8081/tcp ufw allow 3000/tcp ufw allow 9001/tcp ufw allow 7474/tcp ufw enable ``` ### **Secrets Management** ```bash # Docker Secrets echo "notariat_pwd" | docker secret create postgres_password - echo "minio_pwd" | docker secret create minio_password - echo "jwt_secret_key" | docker secret create jwt_secret - # Utilisation dans docker-compose.yml services: postgres: secrets: - postgres_password environment: POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password ``` ## 📊 Configuration de Monitoring ### **Logging Configuration** ```python # services/host_api/logging.py import logging import sys from pythonjsonlogger import jsonlogger def setup_logging(): # Configuration du logger logger = logging.getLogger() logger.setLevel(logging.INFO) # Handler pour stdout handler = logging.StreamHandler(sys.stdout) handler.setLevel(logging.INFO) # Format JSON formatter = jsonlogger.JsonFormatter( '%(asctime)s %(name)s %(levelname)s %(message)s' ) handler.setFormatter(formatter) logger.addHandler(handler) return logger ``` ### **Health Checks** ```python # services/host_api/health.py from fastapi import APIRouter, HTTPException import asyncio import aiohttp router = APIRouter() @router.get("/health") async def health_check(): """Vérification de l'état de tous les services""" services = { "database": await check_database(), "redis": await check_redis(), "minio": await check_minio(), "ollama": await check_ollama(), "neo4j": await check_neo4j(), "opensearch": await check_opensearch() } all_healthy = all(services.values()) if not all_healthy: raise HTTPException(status_code=503, detail=services) return {"status": "healthy", "services": services} async def check_database(): """Vérification de la base de données""" try: # Test de connexion return True except Exception: return False ``` ## 🚀 Configuration de Déploiement ### **Makefile Commands** ```makefile # Makefile .PHONY: help build up down logs clean help: ## Afficher l'aide @echo "Commandes disponibles:" @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' build: ## Construire les images Docker docker-compose build up: ## Démarrer tous les services docker-compose up -d down: ## Arrêter tous les services docker-compose down logs: ## Afficher les logs docker-compose logs -f clean: ## Nettoyer les volumes et images docker-compose down -v docker system prune -f dev: ## Démarrer en mode développement docker-compose -f docker-compose.dev.yml up -d test: ## Exécuter les tests pytest tests/ -v install: ## Installer les dépendances pip install -r requirements-test.txt ``` ### **Scripts de Déploiement** ```bash #!/bin/bash # scripts/deploy.sh set -e echo "🚀 Déploiement du système notarial 4NK_IA" # Vérification des prérequis if ! command -v docker &> /dev/null; then echo "❌ Docker n'est pas installé" exit 1 fi if ! command -v docker-compose &> /dev/null; then echo "❌ Docker Compose n'est pas installé" exit 1 fi # Copie de la configuration cp infra/.env.example infra/.env echo "✅ Configuration copiée" # Construction des images docker-compose -f infra/docker-compose.yml build echo "✅ Images construites" # Démarrage des services docker-compose -f infra/docker-compose.yml up -d echo "✅ Services démarrés" # Attente de la disponibilité echo "⏳ Attente de la disponibilité des services..." sleep 30 # Vérification de la santé curl -f http://localhost:8000/api/health || { echo "❌ L'API n'est pas disponible" exit 1 } echo "✅ Déploiement terminé avec succès" echo "🌐 API: http://localhost:8000" echo "🖥️ Web UI: http://localhost:8081" echo "📊 Grafana: http://localhost:3000" ``` ## 📋 Checklist de Configuration ### **Pré-déploiement** - [ ] **Variables d'environnement** : Fichier `.env` configuré - [ ] **Certificats SSL** : Certificats valides pour HTTPS - [ ] **Firewall** : Ports ouverts et sécurisés - [ ] **Base de données** : PostgreSQL configuré et accessible - [ ] **Redis** : Cache et queue configurés - [ ] **MinIO** : Stockage objet configuré - [ ] **Ollama** : Modèles LLM téléchargés - [ ] **Monitoring** : Prometheus et Grafana configurés ### **Post-déploiement** - [ ] **Health checks** : Tous les services répondent - [ ] **Logs** : Logs structurés et centralisés - [ ] **Métriques** : Collecte des métriques opérationnelle - [ ] **Alertes** : Alertes configurées et testées - [ ] **Backup** : Stratégie de sauvegarde en place - [ ] **Sécurité** : Authentification et autorisation fonctionnelles - [ ] **Performance** : Tests de charge effectués - [ ] **Documentation** : Documentation mise à jour