Pourquoi LiteLLM est la couche manquante des stacks d'IA auto-hébergées
Ollama est excellent pour faire tourner des modèles en local. Open WebUI l'habille d'une interface de chat. Mais dès que vous vous mettez à construire des applications — et plus seulement à discuter — il vous faut un intermédiaire : un proxy qui normalise la surface d'API, suit les coûts par projet et vous permet de changer de modèle sans toucher au code applicatif. C'est précisément le rôle de LiteLLM. Il s'intercale entre votre application et n'importe quel backend LLM, en exposant un unique endpoint compatible OpenAI. Votre code reste identique, que vous acheminiez les requêtes vers Llama 3.1 sur Ollama, Claude 3.5 Haiku ou GPT-4o.
Ce que LiteLLM vous apporte d'emblée
- API unifiée et compatible OpenAI — fonctionne avec tous les SDK, bibliothèques et outils qui ciblent l'API d'OpenAI.
- Plus de 100 intégrations de fournisseurs : Ollama, Anthropic, OpenAI, Azure OpenAI, Mistral, Cohere, Bedrock et bien d'autres.
- Clés d'API virtuelles avec limites de dépenses et de débit par clé — distribuez des clés aux équipes et plafonnez les coûts mensuels.
- Tableau de bord intégré sur /ui avec analyse des dépenses en temps réel, ventilation par modèle et journaux des requêtes.
- Répartition de charge et bascule automatique entre plusieurs endpoints de fournisseurs ou réplicas de modèles.
- Licence Apache 2.0 — aucune télémétrie, aucune remontée d'informations vers l'extérieur, entièrement compatible air-gap une fois associée à Ollama.
Prérequis
Au moins 1 Go de RAM et Ubuntu 22.04. Docker et le plugin Compose installés. Le port 4000 ouvert, ou un reverse proxy Caddy/Nginx pour le HTTPS. C'est tout — LiteLLM est lui-même un proxy Python qui réclame environ 256 Mo ; PostgreSQL absorbe l'essentiel du budget RAM restant. Pour des équipes générant du trafic concurrent, 2 Go sont plus confortables.
Déployer LiteLLM sur un VPS
Provisionner le VPS
Commandez un VPS Solo (2 vCPU, 4 GB, Ubuntu 22.04) : LiteLLM se contente d'un gigaoctet, le plus petit plan du catalogue en sert le double. Connectez-vous en SSH et installez Docker :
curl -fsSL https://get.docker.com | sh. Le plugin Compose est inclus.Générer les secrets
Lancez
openssl rand -hex 32pour générer LITELLM_MASTER_KEY — elle déverrouille le tableau de bord et tous les endpoints d'API d'administration. Créez/opt/litellm/.envavec :LITELLM_MASTER_KEY,UI_USERNAME,UI_PASSWORD,DB_NAME=litellm,DB_USER=litellm,DB_PASSWORD=<strong-password>.Rédiger docker-compose.yml
Créez
/opt/litellm/docker-compose.ymlavec deux services :db(postgres:16-alpine, variables d'environnement issues du .env, volume litellm_db) etlitellm(image ghcr.io/berriai/litellm épinglée sur une version explicite et son condensat@sha256:, jamais surmain-latest— voir « Chaîne d'approvisionnement » plus bas —, port 4000:4000, depends_on db, DATABASE_URL + LITELLM_MASTER_KEY + UI_USERNAME + UI_PASSWORD, volume litellm_config:/app/data). Lancezdocker compose up -d.Ouvrir le tableau de bord
Rendez-vous sur
http://<vps-ip>:4000/uiet connectez-vous avec vos UI_USERNAME / UI_PASSWORD. Vous arrivez sur le tableau de bord de LiteLLM. Allez dans Models pour ajouter votre premier fournisseur. Pour une instance Ollama locale sur le même VPS, définissez le nom du modèle surollama/llama3.1et l'API base surhttp://host.docker.internal:11434. Pour Anthropic, collez votre clé d'API et ajoutezanthropic/claude-3-5-haiku-20241022.Tester la passerelle
Depuis votre poste de travail, testez :
curl http://<vps-ip>:4000/v1/chat/completions -H "Authorization: Bearer <LITELLM_MASTER_KEY>" -H 'Content-Type: application/json' -d '{"model": "ollama/llama3.1", "messages": [{"role": "user", "content": "Hello"}]}'. Vous devriez recevoir une réponse en streaming — acheminée par LiteLLM vers votre Ollama.Distribuer des clés d'API aux équipes
Dans le tableau de bord, sous API Keys, cliquez sur New Key. Donnez-lui une description (par exemple « frontend-team »), définissez
max_budget: 50(USD/mois) et untpm_limitfacultatif. Partagez cette clé avec l'équipe — elle pointe son SDK OpenAI vershttp://<vps-ip>:4000et utilise cette clé. Les dépenses sont suivies par clé dans le tableau de bord.Ajouter le HTTPS avec Caddy
Installez Caddy :
apt install -y caddy. Éditez/etc/caddy/Caddyfile:llm.votre-domaine.com { reverse_proxy localhost:4000 }. Rechargez :systemctl reload caddy. Fermez le port 4000 dans votre pare-feu — tout le trafic passe désormais par le 443 avec TLS automatique.Se connecter la première fois
Ouvrez l'interface d'administration sur /ui : LiteLLM affiche un formulaire identifiant/mot de passe. Saisissez admin et le mot de passe fourni, puis créez vos clés virtuelles depuis le tableau de bord.
Chaîne d'approvisionnement : épingler, vérifier, faire tourner les clés
Une passerelle LLM détient les clés de tous vos fournisseurs : c'est exactement ce qu'un voleur d'identifiants vient chercher. Le fil de signalement ouvert sur le dépôt de LiteLLM (issue 47826) rapporte que les roues de la version 1.107.0 publiées sur PyPI embarquaient trois fichiers étrangers au projet, cook.pth, cook.py et sitecustomize.py, déposés à la racine de site-packages : un voleur d'identifiants et un chargeur d'exécution de code, lancés à chaque démarrage de Python. PyPI a mis cette version en quarantaine. Les mainteneurs indiquent avoir retiré les images Docker malveillantes, et leur billet d'incident décrit un détournement de leur pipeline de publication à partir de jetons de développeurs. Le rapport initial précisait ne pas avoir inspecté les images ; une mise à jour du même fil y a ensuite retrouvé les trois fichiers, dans l'image principale vérifiée, et recommande de traiter toutes les images de cette version comme compromises. Ce guide ne peut pas savoir ce que vous avez tiré à telle date : les quatre gestes ci-dessous le déterminent chez vous.
Savoir ce qui tourne réellement chez vous
Relever le condensat de l'image
Un tag comme
main-latestne dit rien de ce qui s'exécute. Lancezdocker compose imagespuisdocker image inspect --format '{{index .RepoDigests 0}}' ghcr.io/berriai/litellm:main-latest(remplacez par la référence de votre fichier compose). Notez lesha256:obtenu et comparez-le à celui d'une version dont vous avez vérifié la provenance.Chercher les fichiers cités, sans lancer Python
Dans un environnement suspect, tout démarrage de Python rejoue le code malveillant,
pipcompris. Cherchez donc avec un outil qui n'en lance pas :docker compose exec litellm find / -name 'cook.pth' -o -name 'cook.py' -o -name 'sitecustomize.py' -o -name 'litellm-1.107.0.dist-info' 2>/dev/null(si l'image fournitfind). Unsitecustomize.pyisolé ailleurs sur le système peut être légitime ; ce qui alerte, c'est uncook.pthà côté danssite-packages, ou un dossierlitellm-1.107.0.dist-info. Trouver ces fichiers confirme l'exposition ; ne rien trouver ne prouve pas que l'environnement est sain.Lire la version installée
Hors de tout soupçon,
pip show litellm(dans l'environnement virtuel d'une installation directe) oudocker compose exec litellm pip show litellmindique la version. Si c'est la 1.107.0, ou si vous avez un doute sur une image tirée à cette période, passez à la rotation des clés plus bas sans attendre.Chercher les traces d'exécution
Le rapport signale un verrou
/tmp/remote_code_loader.lock, un processuspythonorphelin dont le répertoire courant est/, et un fichier témoin/tmp/.pc_once_*écrit seulement après un envoi réussi. Son absence ne prouve rien : un conteneur recréé efface/tmp. Servez-vous-en comme d'un indice, pas comme d'un verdict.
Épingler par condensat plutôt que par tag
Un tag est un pointeur que l'éditeur déplace ; le condensat @sha256: désigne des octets précis. Dans votre docker-compose.yml, écrivez image: ghcr.io/berriai/litellm:<version>@sha256:<condensat> avec une version explicite publiée avant l'incident ou vérifiée depuis, jamais latest, main-latest ni main-stable. Les mainteneurs recommandent d'épingler une version explicite, et le fil d'issue conseille le condensat. Gardez en tête la limite : un condensat prouve que vous retirez toujours les mêmes octets, pas qui les a construits. Les images de la 1.107.0 auraient été épinglées sans alerte. L'épinglage fige donc une décision que vous avez prise, il ne la remplace pas.
Mettre à jour sans se faire surprendre
- Lisez les notes de version et l'état du fil de sécurité avant de changer de version, plutôt que de laisser
docker compose pullsuivre un tag. - Récupérez le nouveau condensat depuis une machine de test, lancez la passerelle sans clés réelles, vérifiez-en le comportement, puis seulement reportez le condensat en production.
- Quand l'éditeur publie des attestations de provenance, vérifiez-les : elles disent d'où vient l'image, ce qu'un simple condensat ne dit pas.
- Conservez l'ancien condensat dans votre dépôt de configuration : revenir en arrière devient un changement d'une ligne.
- Après toute alerte de sécurité, reconstruisez les conteneurs et les environnements virtuels à neuf plutôt que de nettoyer sur place.
Si la 1.107.0 a tourné chez vous : faire tourner toutes les clés
Selon le rapport, si cette version a démarré sur un hôte joignant Internet, il faut supposer que l'envoi a réussi. Le code décrit lit les variables d'environnement des processus lisibles et, quand DATABASE_URL est défini, extrait les tables où la passerelle stocke les identifiants et les modèles de ses fournisseurs, soit toutes les clés amont qu'elle détient. Le renouvellement est donc à faire pour chaque secret que l'hôte pouvait atteindre, pas seulement pour la clé maîtresse. Révoquez d'abord chez le fournisseur, générez ensuite la clé de remplacement, puis relisez la consommation du dernier mois pour repérer un usage que vous ne reconnaissez pas.
Ce qu'il faut renouveler
- Toutes les clés de fournisseurs enregistrées dans la passerelle : Anthropic, OpenAI, Azure, Mistral, Bedrock et chacune des autres.
LITELLM_MASTER_KEYet toutes les clés virtuelles distribuées aux équipes.- Le mot de passe de la base (
DB_PASSWORDet leDATABASE_URLqui l'embarque), ainsi queUI_PASSWORD. - Tout secret présent dans l'environnement d'un processus de l'hôte : jetons d'API, mots de passe de services voisins, fichiers
.env. - Les clés SSH, jetons Git et identifiants cloud accessibles depuis le VPS, si l'hôte en portait.
- Après rotation, reconstruisez le VPS ou au minimum les conteneurs depuis une image vérifiée : copier de nouveaux secrets dans un hôte compromis les expose à nouveau.
Surveiller les sorties réseau
Le rapport décrit un envoi vers www.litellm.dev, un domaine qui n'est pas celui du projet, et une lecture horaire d'un dépôt GitHub tiers servant de boîte aux lettres pour de nouvelles instructions. Les mainteneurs eux-mêmes jugent qu'une restriction au niveau du réseau est celle qui compte, car un code malveillant ignore la configuration de l'application. Sur un VPS, refusez le trafic sortant par défaut puis autorisez uniquement les points d'accès de vos fournisseurs ; si votre pare-feu filtre par adresse plutôt que par nom, placez un proxy sortant avec liste d'autorisation. À défaut, journalisez les résolutions DNS de l'hôte et alertez sur tout nom que la passerelle n'a aucune raison d'appeler.
Associez LiteLLM à Ollama sur le même VPS pour une stack d'IA entièrement isolée (air-gap). Ollama assure l'inférence des modèles ; LiteLLM ajoute la couche passerelle — acheminement, limitation de débit et suivi de la consommation. Pour les charges de travail sensibles en matière de confidentialité (juridique, finance, médical), cela signifie qu'aucune donnée ne quitte votre infrastructure.
La documentation officielle
Pour la configuration avancée et les options propres à l'outil, référez-vous à la documentation officielle de LiteLLM. Ce guide couvre la mise en ligne sur VPS ; la doc éditeur reste la référence pour les réglages fins, les mises à jour majeures et les cas d'usage spécifiques.