routeur_ia_api / docs /DEPLOYMENT.md
Cyril Dupland
FIrst Commit
d28f1ed

Guide de Déploiement

Table des matières

  1. Développement
  2. Production Local
  3. Docker
  4. Cloud Providers
  5. Monitoring
  6. Sécurité

Développement

Configuration

# Créer environnement virtuel
python -m venv venv
source venv/bin/activate

# Installer dépendances
pip install -r requirements.txt

# Créer .env
cp .env.example .env
# Éditer .env avec vos clés API

Lancement

# Mode développement avec rechargement automatique
python app.py

# ou avec uvicorn directement
uvicorn app:app --reload --port 7860

Production Local

Optimisations

# Générer un secret JWT sécurisé
python -c "import secrets; print(secrets.token_urlsafe(32))"

# Mettre à jour .env
ENVIRONMENT=production
JWT_SECRET_KEY=<secret-généré>

Lancement Production

# Avec workers multiples pour performance
uvicorn app:app \
  --host 0.0.0.0 \
  --port 7860 \
  --workers 4 \
  --log-level info \
  --no-access-log

Avec Gunicorn (recommandé)

# Installer gunicorn
pip install gunicorn

# Lancer
gunicorn app:app \
  --workers 4 \
  --worker-class uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:7860 \
  --timeout 120 \
  --access-logfile - \
  --error-logfile -

Docker

Build

# Build l'image
docker build -t routeur-ia-api:latest .

# Vérifier
docker images | grep routeur-ia-api

Run

# Lancer le conteneur
docker run -d \
  --name routeur-ia-api \
  -p 7860:7860 \
  --env-file .env \
  --restart unless-stopped \
  routeur-ia-api:latest

# Logs
docker logs -f routeur-ia-api

# Arrêter
docker stop routeur-ia-api

# Supprimer
docker rm routeur-ia-api

Docker Compose

Créer docker-compose.yml:

version: '3.8'

services:
  api:
    build: .
    ports:
      - "7860:7860"
    env_file:
      - .env
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:7860/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G

  # Optionnel: Ajouter Redis pour cache
  # redis:
  #   image: redis:7-alpine
  #   ports:
  #     - "6379:6379"
  #   restart: unless-stopped

Lancement:

docker-compose up -d
docker-compose logs -f
docker-compose down

Cloud Providers

Hugging Face Spaces

Le projet est déjà configuré pour Hugging Face Spaces:

  1. Créer un Space sur https://huggingface.co/spaces
  2. Choisir "Docker" comme SDK
  3. Ajouter les secrets dans les Settings:
    • OPENAI_API_KEY
    • MISTRALAI_API_KEY
    • JWT_SECRET_KEY
  4. Push le code

Le Dockerfile et README.md sont déjà configurés.

AWS EC2

# Se connecter à l'instance
ssh -i key.pem ubuntu@<ip>

# Installer Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Cloner le projet
git clone <repo-url>
cd routeur_ia_api

# Créer .env avec les clés
nano .env

# Lancer avec Docker Compose
docker-compose up -d

# Configurer nginx comme reverse proxy (optionnel)
sudo apt install nginx
sudo nano /etc/nginx/sites-available/api

Configuration nginx:

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://localhost:7860;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Google Cloud Run

# Build et push vers GCR
gcloud builds submit --tag gcr.io/PROJECT_ID/routeur-ia-api

# Déployer
gcloud run deploy routeur-ia-api \
  --image gcr.io/PROJECT_ID/routeur-ia-api \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated \
  --set-env-vars "OPENAI_API_KEY=...,MISTRALAI_API_KEY=...,JWT_SECRET_KEY=..."

Azure Container Instances

# Créer un groupe de ressources
az group create --name routeur-ia-rg --location eastus

# Créer un registre de conteneurs
az acr create --resource-group routeur-ia-rg --name routeuriaacr --sku Basic

# Build et push
az acr build --registry routeuriaacr --image routeur-ia-api:latest .

# Déployer
az container create \
  --resource-group routeur-ia-rg \
  --name routeur-ia-api \
  --image routeuriaacr.azurecr.io/routeur-ia-api:latest \
  --dns-name-label routeur-ia-api \
  --ports 7860 \
  --environment-variables \
    OPENAI_API_KEY=... \
    MISTRALAI_API_KEY=... \
    JWT_SECRET_KEY=...

Heroku

# Installer Heroku CLI
curl https://cli-assets.heroku.com/install.sh | sh

# Login
heroku login

# Créer app
heroku create routeur-ia-api

# Ajouter variables d'environnement
heroku config:set OPENAI_API_KEY=...
heroku config:set MISTRALAI_API_KEY=...
heroku config:set JWT_SECRET_KEY=...

# Déployer
git push heroku main

Monitoring

LangSmith

Activez dans .env:

LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=your-key
LANGCHAIN_PROJECT=routeur-ia

Logs

# Docker logs
docker logs -f routeur-ia-api

# Export vers fichier
docker logs routeur-ia-api > logs.txt 2>&1

# Avec rotation (production)
docker run -d \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  routeur-ia-api

Prometheus + Grafana (À implémenter)

# docker-compose.yml
services:
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

Health Checks

# Vérifier la santé de l'API
curl http://localhost:7860/health

# Script de monitoring
while true; do
  status=$(curl -s http://localhost:7860/health | jq -r '.status')
  if [ "$status" != "healthy" ]; then
    echo "API is down!"
    # Envoyer alerte
  fi
  sleep 60
done

Sécurité

Checklist Production

  • HTTPS obligatoire

    # Redirect HTTP to HTTPS
    server {
        listen 80;
        return 301 https://$host$request_uri;
    }
    
  • Secrets sécurisés

    # Ne jamais commiter .env
    # Utiliser un gestionnaire de secrets (AWS Secrets Manager, etc.)
    
  • CORS restreint

    # app.py
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["https://votresite.com"],  # Pas "*"
        allow_credentials=True,
        allow_methods=["GET", "POST"],
        allow_headers=["Authorization", "Content-Type"],
    )
    
  • Rate limiting

    # À implémenter avec slowapi
    from slowapi import Limiter
    limiter = Limiter(key_func=get_remote_address)
    
    @app.post("/completion")
    @limiter.limit("10/minute")
    async def complete(...):
        ...
    
  • JWT robuste

    # Générer avec au moins 32 bytes
    python -c "import secrets; print(secrets.token_urlsafe(32))"
    
  • Validation stricte

    • Déjà implémentée avec Pydantic
    • Taille max fichiers audio: 25 MB
  • Headers de sécurité

    • Déjà implémentés dans SecurityHeadersMiddleware
  • Logs sans données sensibles

    # Ne jamais logger les tokens ou clés API
    logger.info(f"User {user_id} requested completion")  # OK
    logger.info(f"Token: {token}")  # JAMAIS!
    

Firewall

# UFW (Ubuntu)
sudo ufw allow 22/tcp    # SSH
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw enable

# Bloquer accès direct au port 7860 si derrière reverse proxy
# Autoriser seulement depuis localhost

SSL/TLS

# Avec Let's Encrypt (gratuit)
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d api.example.com

# Renouvellement automatique
sudo certbot renew --dry-run

Performance

Optimisations

  1. Workers multiples

    uvicorn app:app --workers 4
    
  2. Connection pooling

    • À implémenter pour base de données future
  3. Cache Redis

    # À implémenter
    @cache.cached(timeout=300)
    async def list_models():
        ...
    
  4. Compression

    from fastapi.middleware.gzip import GZipMiddleware
    app.add_middleware(GZipMiddleware, minimum_size=1000)
    
  5. CDN pour assets

    • Si vous servez du contenu statique

Backup

Base de données (future)

# Backup automatique quotidien
0 2 * * * /usr/bin/docker exec postgres pg_dump -U user db > /backups/db_$(date +\%Y\%m\%d).sql

Configuration

# Backup .env et configuration
tar -czf backup_$(date +%Y%m%d).tar.gz .env config/

Troubleshooting

L'API ne démarre pas

# Vérifier les logs
docker logs routeur-ia-api

# Vérifier les variables d'environnement
docker exec routeur-ia-api env | grep API_KEY

# Vérifier le port
netstat -tlnp | grep 7860

Erreurs de connexion

# Tester depuis le conteneur
docker exec routeur-ia-api curl http://localhost:7860/health

# Tester le réseau
docker network inspect bridge

Performance lente

# Vérifier les ressources
docker stats routeur-ia-api

# Augmenter les workers
# Ajouter cache Redis
# Optimiser les requêtes

Erreurs JWT

# Vérifier JWT_SECRET_KEY dans .env
# Régénérer les tokens
# Vérifier l'expiration (JWT_EXPIRATION_MINUTES)

Rollback

# Docker
docker tag routeur-ia-api:latest routeur-ia-api:backup
docker pull routeur-ia-api:previous
docker stop routeur-ia-api
docker run ... routeur-ia-api:previous

# Git
git revert HEAD
git push

Checklist de Déploiement

  • Variables d'environnement configurées
  • JWT_SECRET_KEY généré sécurisement
  • CORS configuré pour production
  • HTTPS activé
  • Logs configurés
  • Monitoring en place
  • Health checks fonctionnels
  • Backup automatique configuré
  • Firewall configuré
  • Documentation à jour
  • Tests effectués en staging
  • Plan de rollback prêt

Important: Toujours tester en environnement de staging avant production!