Aller au contenu
Développement medium

LiteLLM Proxy Server : gateway LLM pour l'entreprise

17 min de lecture

logo litellm

LiteLLM Proxy Server est une passerelle API qui unifie l’accès à plus de 100 LLM (OpenAI, Anthropic, Ollama, Azure…) via une interface compatible OpenAI. En entreprise, il résout trois problèmes majeurs : centraliser les clés API, contrôler les coûts (budgets par équipe), et restreindre l’accès (modèles autorisés, rate limits).

Ce guide vous accompagne de l’installation jusqu’à la mise en production. À la fin, vous saurez :

  • Déployer un proxy local avec Docker et Ollama
  • Créer des utilisateurs, équipes et clés virtuelles
  • Limiter l’accès par modèle, budget et rate limit
  • Monitorer la consommation en temps réel
  • Architecture : comment LiteLLM s’insère entre vos applications et les LLM
  • Lab Docker : proxy fonctionnel avec Ollama (gratuit, local)
  • Gestion des accès : utilisateurs, équipes, clés virtuelles
  • Restrictions : modèles autorisés, budgets, rate limits (RPM/TPM)
  • Production : Docker Compose avec PostgreSQL et persistance

Sans proxy, chaque application gère ses propres clés API :

Sans proxyAvec LiteLLM Proxy
Clés API éparpillées dans le codeUne seule clé par équipe
Impossible de suivre les coûtsBudget par user/team/clé
Dépendance à un fournisseurFallback automatique
Pas de rate limiting centraliséRPM/TPM par clé
FonctionnalitéOpen SourceEnterprise (250$/mois)
100+ LLM supportés
Clés virtuelles
Budgets & rate limits
Interface web
SSO/OIDC
Métriques Prometheus
Support SLA

Nous allons créer un lab complet sans clé API payante. Ollama exécute les modèles localement, LiteLLM Proxy les expose via une API compatible OpenAI.

Architecture LiteLLM Proxy avec Docker et Ollama

  • Docker installé
  • Ollama installé (ollama.ai)
  • 4 Go de RAM disponibles pour les modèles

Ollama doit écouter sur toutes les interfaces pour être accessible depuis Docker :

Fenêtre de terminal
# Arrêter Ollama s'il tourne
pkill ollama
# Redémarrer en écoutant sur toutes les interfaces
OLLAMA_HOST=0.0.0.0 ollama serve &
# Vérifier
curl -s http://localhost:11434/api/tags | jq '.models[].name'
Fenêtre de terminal
# Modèle léger pour les tests (352 Mo)
ollama pull qwen2:0.5b
# Modèle plus capable (1.3 Go)
ollama pull llama3.2:1b
# Vérifier les modèles disponibles
ollama list

Sortie attendue :

NAME ID SIZE MODIFIED
llama3.2:1b baf6a787fdff 1.3 GB 2 minutes ago
qwen2:0.5b 6f48b936a09f 352 MB 3 minutes ago

Créez un dossier pour le lab :

Fenêtre de terminal
mkdir -p ~/Projets/litellm-lab/config
cd ~/Projets/litellm-lab

Créez le fichier config/proxy-config.yaml :

# LiteLLM Proxy Server - Configuration Lab
model_list:
# Modèle principal
- model_name: llama
litellm_params:
model: ollama/llama3.2:1b
api_base: http://host.docker.internal:11434
# Modèle secondaire (plus rapide)
- model_name: qwen
litellm_params:
model: ollama/qwen2:0.5b
api_base: http://host.docker.internal:11434
# Alias pour compatibilité OpenAI
- model_name: gpt-3.5-turbo
litellm_params:
model: ollama/qwen2:0.5b
api_base: http://host.docker.internal:11434
- model_name: gpt-4
litellm_params:
model: ollama/llama3.2:1b
api_base: http://host.docker.internal:11434
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
json_logs: true
router_settings:
routing_strategy: simple-shuffle
num_retries: 2
timeout: 120

PostgreSQL stocke les utilisateurs, clés et métriques :

Fenêtre de terminal
docker run -d --name litellm-postgres \
-e POSTGRES_USER=litellm \
-e POSTGRES_PASSWORD=litellm_secure_pwd \
-e POSTGRES_DB=litellm \
-p 5432:5432 \
postgres:16-alpine

Vérification :

Fenêtre de terminal
docker ps | grep litellm-postgres
# Doit afficher le conteneur en cours d'exécution
Fenêtre de terminal
docker run -d --name litellm-proxy \
-p 4000:4000 \
-v $(pwd)/config/proxy-config.yaml:/app/config.yaml \
-e LITELLM_MASTER_KEY=sk-litellm-lab-2026-demo \
-e DATABASE_URL="postgresql://litellm:litellm_secure_pwd@172.17.0.1:5432/litellm" \
-e UI_USERNAME=admin \
-e UI_PASSWORD=AdminSecure2026 \
--add-host=host.docker.internal:host-gateway \
ghcr.io/berriai/litellm:main-latest \
--config /app/config.yaml --port 4000

Vérifier les logs :

Fenêtre de terminal
docker logs litellm-proxy --tail 20

Sortie attendue :

██╗ ██╗████████╗███████╗██╗ ██╗ ███╗ ███╗
██║ ██║╚══██╔══╝██╔════╝██║ ██║ ████╗ ████║
...
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:4000
Fenêtre de terminal
# Lister les modèles disponibles
curl -s http://localhost:4000/v1/models \
-H "Authorization: Bearer sk-litellm-lab-2026-demo" | jq '.data[].id'

Sortie attendue :

"llama"
"qwen"
"gpt-3.5-turbo"
"gpt-4"
Fenêtre de terminal
# Tester une complétion
curl -s http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-litellm-lab-2026-demo" \
-d '{
"model": "qwen",
"messages": [{"role": "user", "content": "Dis bonjour en une phrase"}],
"max_tokens": 30
}' | jq '.choices[0].message.content'

Sortie attendue :

"Bonjour! Comment puis-je vous aider aujourd'hui?"

LiteLLM propose une hiérarchie à 3 niveaux : UtilisateursÉquipesClés. Chaque niveau peut avoir ses propres restrictions.

Fenêtre de terminal
curl -s http://localhost:4000/user/new \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-litellm-lab-2026-demo" \
-d '{
"user_id": "alice@example.com",
"user_email": "alice@example.com",
"max_budget": 5.0,
"budget_duration": "30d",
"models": ["qwen"],
"metadata": {"role": "developer", "department": "engineering"}
}' | jq '{user_id, max_budget, models}'

Sortie :

{
"user_id": "alice@example.com",
"max_budget": 5.0,
"models": ["qwen"]
}
Fenêtre de terminal
curl -s http://localhost:4000/team/new \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-litellm-lab-2026-demo" \
-d '{
"team_alias": "ml-team",
"max_budget": 50.0,
"budget_duration": "30d",
"models": ["qwen", "llama"],
"tpm_limit": 100000,
"rpm_limit": 60,
"metadata": {"project": "ml-pipeline"}
}' | jq '{team_id, team_alias, max_budget, rpm_limit}'

Sortie :

{
"team_id": "0b71f785-5fec-48c0-a76d-87d3289fafb4",
"team_alias": "ml-team",
"max_budget": 50.0,
"rpm_limit": 60
}

Les clés virtuelles permettent de distribuer des accès sans partager la master key.

Fenêtre de terminal
curl -s http://localhost:4000/key/generate \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-litellm-lab-2026-demo" \
-d '{
"key_alias": "dev-team-key",
"max_budget": 10.0,
"budget_duration": "30d",
"models": ["qwen", "llama"],
"metadata": {"team": "dev", "project": "demo"}
}' | jq '{key, max_budget, models}'

Sortie :

{
"key": "sk-Li3j_hWPrxs5MY3m0DBAJg",
"max_budget": 10.0,
"models": ["qwen", "llama"]
}

Cette clé est limitée à qwen et llama. Testons l’accès à gpt-4 :

Fenêtre de terminal
curl -s http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-Li3j_hWPrxs5MY3m0DBAJg" \
-d '{"model": "gpt-4", "messages": [{"role": "user", "content": "test"}]}' \
| jq '.error'

Sortie (accès refusé) :

{
"message": "key not allowed to access model. This key can only access models=['qwen', 'llama']. Tried to access gpt-4",
"type": "key_model_access_denied",
"code": "401"
}

Créer une clé liée à un utilisateur et une équipe

Section intitulée « Créer une clé liée à un utilisateur et une équipe »
Fenêtre de terminal
curl -s http://localhost:4000/key/generate \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-litellm-lab-2026-demo" \
-d '{
"key_alias": "alice-personal-key",
"user_id": "alice@example.com",
"team_id": "0b71f785-5fec-48c0-a76d-87d3289fafb4",
"max_budget": 2.0
}' | jq '{key, user_id, team_id, max_budget}'

Le rate limiting protège contre les abus et contrôle la consommation.

Fenêtre de terminal
curl -s http://localhost:4000/key/generate \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-litellm-lab-2026-demo" \
-d '{
"key_alias": "rate-limited-key",
"rpm_limit": 2,
"tpm_limit": 100,
"models": ["qwen"]
}' | jq '{key, rpm_limit, tpm_limit}'

Sortie :

{
"key": "sk-9MwdeGpwsUJ9z0NPftXz4A",
"rpm_limit": 2,
"tpm_limit": 100
}

Envoyez 3 requêtes rapides (la limite est de 2/minute) :

Fenêtre de terminal
KEY="sk-9MwdeGpwsUJ9z0NPftXz4A"
for i in 1 2 3; do
echo "=== Requête $i ==="
curl -s http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $KEY" \
-d '{"model": "qwen", "messages": [{"role": "user", "content": "1"}], "max_tokens": 5}' \
| jq -c '{ok: .choices[0].message.content, error: .error.message}'
done

Sortie :

=== Requête 1 ===
{"ok":"Hello! It seems like","error":null}
=== Requête 2 ===
{"ok":"Hello! How can I","error":null}
=== Requête 3 ===
{"ok":null,"error":"Rate limit exceeded... Current limit: 2, Remaining: 0. Limit resets at: ..."}
Fenêtre de terminal
curl -s http://localhost:4000/spend/tags \
-H "Authorization: Bearer sk-litellm-lab-2026-demo" | jq .

Accédez à l’interface web http://localhost:4000/ui pour visualiser :

  • Dépenses par modèle, utilisateur, équipe
  • Graphiques de consommation dans le temps
  • Alertes de dépassement de budget

Pour un déploiement production, utilisez Docker Compose avec persistance :

docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:16-alpine
container_name: litellm-db
environment:
POSTGRES_USER: litellm
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
POSTGRES_DB: litellm
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U litellm"]
interval: 5s
timeout: 5s
retries: 5
litellm:
image: ghcr.io/berriai/litellm:main-latest
container_name: litellm-proxy
ports:
- "4000:4000"
environment:
LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY}
DATABASE_URL: postgresql://litellm:${POSTGRES_PASSWORD:-changeme}@postgres:5432/litellm
UI_USERNAME: ${UI_USERNAME:-admin}
UI_PASSWORD: ${UI_PASSWORD}
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
volumes:
- ./config/proxy-config.yaml:/app/config.yaml:ro
depends_on:
postgres:
condition: service_healthy
command: ["--config", "/app/config.yaml", "--port", "4000"]
restart: unless-stopped
volumes:
postgres_data:

Fichier .env :

Fenêtre de terminal
LITELLM_MASTER_KEY=sk-your-secure-master-key-here
POSTGRES_PASSWORD=your-secure-db-password
UI_USERNAME=admin
UI_PASSWORD=YourSecureUIPassword!
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...

Lancement :

Fenêtre de terminal
docker compose up -d
docker compose logs -f litellm
SymptômeCause probableSolution
Cannot connect to host localhost:11434Ollama écoute sur 127.0.0.1Lancer avec OLLAMA_HOST=0.0.0.0
Unable to find Prisma binariesInstallation pip sans DockerUtiliser l’image Docker officielle
Rate limit exceededLimite atteinteAttendre le reset ou augmenter la limite
key not allowed to access modelModèle non autoriséAjouter le modèle à la clé
Authentication ErrorMaster key incorrecteVérifier LITELLM_MASTER_KEY
Fenêtre de terminal
# Logs du proxy
docker logs litellm-proxy --tail 100
# Vérifier la connexion PostgreSQL
docker exec litellm-proxy psql $DATABASE_URL -c "SELECT 1"
# Lister toutes les clés (tokens hachés)
curl -s http://localhost:4000/key/list \
-H "Authorization: Bearer sk-litellm-lab-2026-demo" | jq .
# Health check
curl -s http://localhost:4000/health | jq .
  1. LiteLLM Proxy unifie l’accès à 100+ LLM via une API compatible OpenAI
  2. Hiérarchie 3 niveaux : User → Team → Key, chacun avec ses restrictions
  3. Restrictions par clé : modèles autorisés, budget, rate limits (RPM/TPM)
  4. Docker recommandé pour éviter les problèmes de dépendances (Prisma)
  5. PostgreSQL requis pour la persistance des clés, users et métriques
  6. Production : HTTPS obligatoire, master key sécurisée, backups

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn