Une stack IA locale transforme une démonstration en service durable. Elle sépare le moteur d'inférence, l'interface, les documents, le stockage et l'observation. Chaque brique peut évoluer sans rendre le système opaque.
Définir un contrat minimal
Avant de choisir les outils, écrivez le résultat attendu : qui utilise le service, depuis quel réseau, avec quel modèle, quels documents et quelle disponibilité. Fixez aussi une procédure de retour arrière.
Les briques du service

Le runtime charge le modèle et expose une API. L'interface gère les conversations. Un service documentaire découpe et indexe les fichiers. Un proxy peut gérer TLS et l'authentification. La supervision collecte les erreurs et les mesures.
Containeriser avec une intention claire
Les containers rendent les dépendances et les volumes explicites. Ils facilitent la mise à jour et le retour à une version précédente. Ils ne remplacent pas la compréhension du réseau ou du stockage.
Déclarez pour chaque service : l'image et sa version, les ports, les volumes persistants, les variables de configuration, la politique de redémarrage et les ressources disponibles.
Un fichier Compose de départ
Ce fichier assemble Ollama et Open WebUI. Les versions viennent d'un fichier .env, l'API d'Ollama reste sur le réseau interne des containers et seule l'interface est publiée, sur la machine elle-même :
services:
ollama:
image: ollama/ollama:${OLLAMA_TAG:?définir OLLAMA_TAG dans .env}
restart: unless-stopped
volumes:
- ollama-modeles:/root/.ollama
healthcheck:
test: ["CMD", "ollama", "list"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
open-webui:
image: ghcr.io/open-webui/open-webui:${OPENWEBUI_TAG:?définir OPENWEBUI_TAG dans .env}
restart: unless-stopped
depends_on:
ollama:
condition: service_healthy
environment:
- OLLAMA_BASE_URL=http://ollama:11434
ports:
- "127.0.0.1:3000:8080"
volumes:
- ./donnees/open-webui:/app/backend/data
volumes:
ollama-modeles:
Le fichier .env, placé à côté, fixe les versions testées. Relevez-les sur les pages Releases de GitHub des deux projets. Le fichier Compose refuse de démarrer tant qu'elles sont vides :
OLLAMA_TAG=
OPENWEBUI_TAG=
Le bloc deploy réserve les GPU NVIDIA et demande le NVIDIA Container Toolkit sur l'hôte. Retirez-le pour un essai sur CPU. Pour un GPU AMD, Ollama publie une image rocm qui demande l'accès aux périphériques /dev/kfd et /dev/dri.
docker compose up -d
docker compose ps
docker compose exec ollama ollama pull qwen3:8b
Ouvrez http://localhost:3000, créez le compte administrateur et choisissez le modèle. Pour mettre à jour, modifiez une version dans .env, puis lancez docker compose pull et docker compose up -d. Pour revenir en arrière, remettez l'ancienne version et relancez docker compose up -d.
Gérer les modèles et les volumes
Les poids occupent beaucoup d'espace, mais ils peuvent souvent être retéléchargés. Les conversations, comptes, configurations et index documentaires demandent une sauvegarde. Montez ces données dans des volumes identifiés.
Séparez si possible le cache de modèles des données métier. Vous pourrez nettoyer ou reconstruire le cache sans toucher aux documents et aux métadonnées.
Dans le fichier ci-dessus, les modèles vivent dans un volume nommé, que l'on peut retélécharger, tandis que les comptes et conversations d'Open WebUI sont dans le dossier donnees. C'est ce dossier qu'il faut sauvegarder. Arrêtez brièvement l'interface pour obtenir une copie cohérente de sa base :
docker compose stop open-webui
restic -r /mnt/sauvegarde/restic backup ./donnees ./compose.yaml ./.env
docker compose start open-webui
Réseau et accès
Exposez uniquement le proxy ou l'interface nécessaire. Gardez l'API du runtime sur un réseau interne de containers si aucun client externe n'en a besoin. Limitez l'administration à un réseau ou un VPN de confiance.
Vérifier la santé
Une supervision minimale suit l'espace disque, la RAM, la VRAM, la température, la disponibilité de l'API et les erreurs. Ajoutez un test synthétique qui envoie une petite requête et vérifie une réponse.
Le healthcheck du fichier Compose vérifie déjà que le serveur Ollama répond. Un test synthétique va plus loin : il demande une vraie génération, que vous pouvez planifier et surveiller avec Uptime Kuma ou une tâche cron.
docker compose exec ollama ollama run qwen3:8b "Réponds uniquement par OK."
Les journaux doivent aider au diagnostic sans conserver inutilement les prompts sensibles. Configurez leur rotation pour éviter qu'ils saturent le disque. Pour tous les containers, placez ce contenu dans /etc/docker/daemon.json, puis redémarrez Docker avec sudo systemctl restart docker :
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}
Chaque container garde alors au plus trois fichiers de 10 Mo. Le réglage s'applique aux containers créés après le redémarrage : recréez-les avec docker compose up -d --force-recreate.
Déployer par étapes
- Lancez le runtime et testez une inférence locale.
- Ajoutez l'interface sur le même hôte.
- Fixez les volumes et sauvegardez la configuration.
- Placez le proxy et l'authentification.
- Ajoutez les documents et mesurez la recherche.
- Activez la supervision et les alertes utiles.
- Testez une mise à jour puis un retour arrière.
Préparer l'évolution
Documentez les dépendances avant d'ajouter un deuxième GPU, un autre nœud ou plusieurs utilisateurs. La distribution augmente les problèmes de réseau, de stockage partagé et de planification. Une seule machine bien observée peut servir longtemps.
Le système est terminé quand il se restaure
Le vrai test n'est pas le premier lancement. C'est la capacité à expliquer chaque brique, mettre à jour sans improvisation, détecter une panne et restaurer les données importantes. À ce stade, votre homelab devient une infrastructure maîtrisée.
L’essentiel
- Écrivez d'abord le contrat : utilisateurs, réseau, modèle, documents, disponibilité et retour arrière.
- Épinglez les versions ; mettez à jour volontairement, en sachant revenir en arrière.
- Gardez l'API du runtime sur le réseau interne et publiez seulement l'interface.
- Séparez le cache de modèles, retéléchargeable, des données à sauvegarder.
- Le système est terminé quand il se restaure, pas quand il démarre.
Testez-vous
Répondez de tête ou par écrit, puis vérifiez. Se tester juste après la lecture aide à retenir.
Pourquoi éviter le tag latest pour un service important ?
Voir la réponse
Une mise à jour implicite peut changer le comportement ou casser la compatibilité sans que vous l'ayez décidé. Une version épinglée rend chaque mise à jour volontaire et réversible.
Dans le fichier Compose de la leçon, pourquoi le port 11434 d'Ollama n'est-il pas publié ?
Voir la réponse
Seule l'interface a besoin du runtime. Elle le joint par le réseau interne des containers. Ne pas publier le port évite d'exposer l'API à d'autres machines.
Quelle différence entre le healthcheck et le test synthétique ?
Voir la réponse
Le healthcheck vérifie que le serveur Ollama répond. Le test synthétique demande une vraie génération et vérifie donc toute la chaîne, modèle compris.
Sources et pour aller plus loin
- Accès GPU avec Docker Compose : le bloc
deployet ses options. - Installer le NVIDIA Container Toolkit : prérequis pour utiliser un GPU NVIDIA dans un container.
- Ollama avec Docker : images CPU, NVIDIA et AMD.
- Pilote de journaux json-file : rotation des journaux des containers.