
- Suppression des fichiers de documentation temporaires - Mise à jour des URLs pour rester en localhost uniquement - Finalisation de la documentation complète - Nettoyage du dépôt
751 lines
17 KiB
Markdown
751 lines
17 KiB
Markdown
# 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
|