
Avant l'assistant, avant l'interface, il faut le socle — les services dont tout le reste dépend. Cette première étape du fil rouge assemble, en un seul Docker Compose, les trois fondations de la stack souveraine : Ollama pour les modèles, Qdrant pour la base vectorielle, LiteLLM comme passerelle d'accès aux modèles. Et elle le fait sécurisé dès le départ : un réseau interne, des services non exposés, des clés sur chaque accès, des ports liés à la machine locale. Vous obtiendrez un socle vérifié par six tests — la fondation sur laquelle l'assistant documentaire viendra se brancher. Public visé : développeur qui a suivi le parcours et veut l'assembler en infrastructure réelle.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Assembler Ollama, Qdrant et LiteLLM en un Docker Compose.
- Accélérer Ollama par GPU et le garder non exposé.
- Protéger Qdrant et LiteLLM par des clés.
- Isoler les services sur un réseau interne, lier les ports à
localhost. - Valider le socle avant de bâtir dessus.
Prérequis
Section intitulée « Prérequis »- Docker avec le runtime nvidia pour l'accélération GPU.
- Avoir lu l'architecture de la stack souveraine.
- Connaître Qdrant et le proxy LiteLLM.
Les trois services du socle
Section intitulée « Les trois services du socle »Le socle réunit trois rôles distincts, chacun déjà connu du parcours, désormais assemblés.
Ollama sert les modèles — le modèle de chat Mistral Small 3.2 et le modèle d'embedding nomic-embed-text. Mistral Small est un modèle à poids ouverts de Mistral AI, une entreprise française : pour une stack qui se veut souveraine, le modèle relève du même périmètre de maîtrise que le reste de l'infrastructure. Ollama s'exécute sur GPU pour des temps de réponse acceptables.
Qdrant est la base vectorielle : c'est elle qui stockera, à l'étape suivante, le corpus indexé de l'assistant documentaire.
LiteLLM est la passerelle : un point d'accès unique aux modèles, qui ajoute une clé maître, et qui découplera l'assistant du détail des modèles servis derrière.
Ces trois services sont décrits dans un seul fichier compose.yml. Un docker compose up lève tout le socle.
Ollama : les modèles, sur GPU, jamais exposé
Section intitulée « Ollama : les modèles, sur GPU, jamais exposé »Le service Ollama réclame deux choses : l'accès au GPU, et un volume pour conserver les modèles téléchargés.
ollama: image: ollama/ollama:0.12.3@sha256:c622a7adec67cf5bd7fe1802b7e26aa583a955a54e91d132889301f50c3e0bd0 restart: unless-stopped networks: - souveraine volumes: - ollama_data:/root/.ollama deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu]Le bloc deploy.resources.reservations.devices réserve le GPU au conteneur — c'est lui qui rend l'inférence rapide. Le volume ollama_data conserve les modèles : ils ne sont téléchargés qu'une fois.
Un point décisif de sécurité : Ollama n'a aucune ligne ports. Il n'est pas exposé — ni à l'hôte, ni au réseau. Seuls les autres services du socle le joignent, par son nom sur le réseau interne. Un service sans port publié n'offre aucune surface d'attaque depuis l'extérieur.
Qdrant : la base vectorielle protégée
Section intitulée « Qdrant : la base vectorielle protégée »Qdrant stocke les vecteurs. Par défaut, son API est ouverte — inacceptable pour une stack qu'on veut sûre. On lui impose une clé d'API.
qdrant: image: qdrant/qdrant:v1.18.0@sha256:b3063c673f3973877c038eeecc392bad5011f072ee7892b56c9a8e204a3bdea9 restart: unless-stopped networks: - souveraine environment: QDRANT__SERVICE__API_KEY: ${QDRANT_API_KEY} volumes: - qdrant_data:/qdrant/storage ports: - "127.0.0.1:6333:6333"La variable QDRANT__SERVICE__API_KEY active la protection : toute requête à l'API doit désormais porter l'en-tête api-key. Sans clé, Qdrant répond 403.
Le port, lui, est publié sur 127.0.0.1:6333 — et non 0.0.0.0:6333. La différence est capitale : lié à 127.0.0.1, Qdrant n'est joignable que depuis la machine hôte, jamais depuis le réseau. C'est ce dont l'assistant et les tests ont besoin, sans ouvrir la base à l'extérieur.
LiteLLM : la passerelle d'accès aux modèles
Section intitulée « LiteLLM : la passerelle d'accès aux modèles »LiteLLM s'intercale entre les applications et Ollama. Il offre une API compatible OpenAI unique, protégée par une clé maître, et un fichier de configuration qui déclare les modèles.
litellm: image: ghcr.io/berriai/litellm:main-v1.74.3-stable@sha256:229665e372493ab0948f36ca813a5a20f352e258424383d6a7043bf088eb12fb command: ["--config", "/app/config.yaml", "--port", "4000"] networks: - souveraine volumes: - ./litellm-config.yaml:/app/config.yaml:ro environment: LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY} ports: - "127.0.0.1:4000:4000" depends_on: - ollamaLa configuration relie les noms de modèles publics à leur adresse réelle sur le réseau interne — http://ollama:11434.
model_list: - model_name: mistral-small litellm_params: model: ollama_chat/mistral-small3.2 api_base: http://ollama:11434 - model_name: nomic-embed-text litellm_params: model: ollama/nomic-embed-text api_base: http://ollama:11434
litellm_settings: drop_params: trueDeux détails comptent. Le préfixe ollama_chat/ pour le chat, ollama/ pour les embeddings — chacun route vers le bon mécanisme d'Ollama. Et drop_params: true : un client OpenAI envoie des paramètres qu'Ollama ne connaît pas (comme encoding_format) ; sans ce réglage, LiteLLM rejette la requête. Avec, il retire poliment les paramètres inconnus.
Sécuriser le socle dès le départ
Section intitulée « Sécuriser le socle dès le départ »La sécurité ne s'ajoute pas après coup — elle est dans la structure du compose.yml. Quatre choix la portent.
Le réseau interne d'abord. Tous les services rejoignent un réseau souveraine ; ils se parlent par leur nom de service, jamais par une adresse exposée. Ollama, qui n'a aucun port publié, n'existe que sur ce réseau.
Les ports liés à 127.0.0.1 ensuite. Qdrant et LiteLLM doivent être joignables depuis l'hôte — pour l'assistant, pour les tests. Mais 127.0.0.1: les enferme sur l'hôte : invisibles depuis le réseau. L'exposition vers de vrais utilisateurs est réservée à l'étape suivante, derrière un reverse proxy.
Les clés sur chaque accès : clé d'API Qdrant, clé maître LiteLLM. Aucun service n'est ouvert.
Les secrets hors du dépôt enfin. Les clés vivent dans un fichier .env, ignoré par Git. Un .env.example sert de modèle, sans valeur réelle. On ne versionne jamais un secret.
Démarrer et valider
Section intitulée « Démarrer et valider »Le socle se lève en quelques commandes, puis se vérifie.
cp .env.example .env # puis y mettre des valeurs généréesdocker compose up -ddocker compose exec ollama ollama pull mistral-small3.2docker compose exec ollama ollama pull nomic-embed-textUn socle qu'on ne vérifie pas est un socle dont on ne sait rien. La suite de tests du lab le contrôle sur six points : la configuration du proxy (test déterministe), la santé de Qdrant, le fait que Qdrant et LiteLLM exigent une clé — deux tests de sécurité —, et enfin un chat et un embedding réels à travers la passerelle. Six tests verts : le socle est prêt à porter l'assistant.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
| Ollama démarre sans GPU | Runtime nvidia absent | Installer le nvidia container toolkit |
model not found | Modèles non tirés | docker compose exec ollama ollama pull ... |
| Embedding rejeté par le proxy | drop_params absent | Ajouter litellm_settings: drop_params: true |
| Qdrant accepte des requêtes sans clé | QDRANT__SERVICE__API_KEY non défini | Définir la variable, vérifier le .env |
litellm ne joint pas Ollama | api_base incorrect | Pointer sur http://ollama:11434 (nom de service) |
À retenir
Section intitulée « À retenir »- Le socle réunit Ollama, Qdrant et LiteLLM en un seul Docker Compose.
- Ollama tourne sur GPU et n'a aucun port — il vit seulement sur le réseau interne.
- Qdrant et LiteLLM sont protégés par des clés ; aucun service n'est ouvert.
- Les ports sont liés à
127.0.0.1— joignables depuis l'hôte, pas depuis le réseau. drop_params: trueest obligatoire pour servir des embeddings Ollama via LiteLLM.- Les secrets vivent dans un
.envnon versionné ; le socle se valide par des tests.