# Guide de Déploiement ## Table des matières 1. [Développement](#développement) 2. [Production Local](#production-local) 3. [Docker](#docker) 4. [Cloud Providers](#cloud-providers) 5. [Monitoring](#monitoring) 6. [Sécurité](#sécurité) ## Développement ### Configuration ```bash # 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 ```bash # Mode développement avec rechargement automatique python app.py # ou avec uvicorn directement uvicorn app:app --reload --port 7860 ``` ## Production Local ### Optimisations ```bash # 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= ``` ### Lancement Production ```bash # 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é) ```bash # 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 ```bash # Build l'image docker build -t routeur-ia-api:latest . # Vérifier docker images | grep routeur-ia-api ``` ### Run ```bash # 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`: ```yaml 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: ```bash 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 ```bash # Se connecter à l'instance ssh -i key.pem ubuntu@ # Installer Docker curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh # Cloner le projet git clone 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: ```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 ```bash # 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 ```bash # 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 ```bash # 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`: ```env LANGCHAIN_TRACING_V2=true LANGCHAIN_API_KEY=your-key LANGCHAIN_PROJECT=routeur-ia ``` ### Logs ```bash # 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) ```yaml # 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 ```bash # 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** ```nginx # Redirect HTTP to HTTPS server { listen 80; return 301 https://$host$request_uri; } ``` - [ ] **Secrets sécurisés** ```bash # Ne jamais commiter .env # Utiliser un gestionnaire de secrets (AWS Secrets Manager, etc.) ``` - [ ] **CORS restreint** ```python # 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** ```python # À 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** ```bash # 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** ```python # 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 ```bash # 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 ```bash # 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** ```bash uvicorn app:app --workers 4 ``` 2. **Connection pooling** - À implémenter pour base de données future 3. **Cache Redis** ```python # À implémenter @cache.cached(timeout=300) async def list_models(): ... ``` 4. **Compression** ```python 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) ```bash # Backup automatique quotidien 0 2 * * * /usr/bin/docker exec postgres pg_dump -U user db > /backups/db_$(date +\%Y\%m\%d).sql ``` ### Configuration ```bash # Backup .env et configuration tar -czf backup_$(date +%Y%m%d).tar.gz .env config/ ``` ## Troubleshooting ### L'API ne démarre pas ```bash # 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 ```bash # Tester depuis le conteneur docker exec routeur-ia-api curl http://localhost:7860/health # Tester le réseau docker network inspect bridge ``` ### Performance lente ```bash # Vérifier les ressources docker stats routeur-ia-api # Augmenter les workers # Ajouter cache Redis # Optimiser les requêtes ``` ### Erreurs JWT ```bash # Vérifier JWT_SECRET_KEY dans .env # Régénérer les tokens # Vérifier l'expiration (JWT_EXPIRATION_MINUTES) ``` ## Rollback ```bash # 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!