Ollama in Docker Compose mit GPU und persistenter Model-Speicherung
Compose-first Ollama-Server mit GPU und Persistenz.
Ollama läuft hervorragend auf Bare-Metal-Systemen. Es wird noch interessanter, wenn man es wie einen Dienst behandelt: mit einem stabilen Endpunkt, festgelegten Versionen, persistentem Speicher und einer GPU, die entweder verfügbar ist oder eben nicht.
Dieser Beitrag konzentriert sich auf ein Ziel: einen reproduzierbaren lokalen oder single-node Ollama-„Server" mit Docker Compose, inklusive GPU-Beschleunigung und persistenter Modell-Speicherung.

Er bewusst auf allgemeine Docker- und Compose-Grundlagen verzichtet. Wenn Sie eine kompakte Liste der am häufigsten genutzten Befehle (Images, Container, Volumes, docker compose) benötigen, ist das Docker-Spickzettel ein guter Begleiter.
Wenn Sie HTTPS vor Ollama einsetzen möchten, sowie korrektes Streaming und WebSocket-Proxying und Edge-Kontrollen (Authentifizierung, Timeouts, Ratenlimits), siehe Ollama hinter einem Reverse Proxy mit Caddy oder Nginx für HTTPS-Streaming.
Zu der Frage, wie Ollama neben vLLM, Docker Model Runner, LocalAI und den Trade-offs im Cloud-Hosting steht, siehe LLM Hosting in 2026: Lokale, Self-Hosted- und Cloud-Infrastrukturen im Vergleich.
Sobald dieser Compose-Stack echten parallelen Traffic verarbeitet, ist die nächste Frage oft, ob Ollama überhaupt noch der richtige Motor darunter ist. Ollama zu vLLM: Wann Sie Ihren lokalen LLM-Server migrieren sollten liefert einen gestuften Migrationspfad, bei dem beide Container während der Validierung parallel laufen bleiben.
Wann Compose eine Bare-Metal-Installation schlägt
Eine Native-Installation ist für einen Entwickler auf einer Maschine reibungslos. Sobald einer der folgenden Punkte zutrifft, gewinnt Compose in Bezug auf die Bedienbarkeit:
Ein Teams-Setup profitiert davon, dass die Service-Definition eine Datei ist, die man überprüfen, versionieren und teilen kann. Ein Single-Node-Server profitiert davon, dass Upgrades in ein Bumpen des Image-Tags und einen Neustart übergehen, während der Modellspeicher an Ort und Stelle bleibt (solange er auf einem Volume liegt). Ollama lebt oft auch nebenbei mit Sidecars: einer Web-UI, einem Reverse Proxy, einem Auth-Gateway, einer Vektor-DB oder einem Agent-Runtime. Compose ist gut darin, „mit einem Befehl den gesamten Stack zu starten", ohne den Host zu einer Snowflake (einzigartigen, schwer reproduzierbaren Umgebung) zu machen.
Dieser Ansatz passt gut zu dem, wie das offizielle Ollama-Container-Image entworfen ist: Das Image führt standardmäßig ollama serve, stellt den Port 11434 bereit und ist so konzipiert, dass der Zustand unter einem mountbaren Verzeichnis gehalten wird. Der vollständige Satz an OLLAMA_*-Umgebungsvariablen, die ollama serve liest – OLLAMA_HOST, OLLAMA_CONTEXT_LENGTH, OLLAMA_KEEP_ALIVE, OLLAMA_NUM_PARALLEL und die restlichen – ist im Ollama CLI-Spickzettel dokumentiert.
Ein Compose-Gerüst, das tatsächlich nützlich für Ollama ist
Beginnen Sie mit zwei Entscheidungen:
Erstens, wie Sie Versionen festlegen (Pin). Das Docker Hub-Image ist ollama/ollama, daher können Sie ein bestimmtes Tag in der .env festpinnen, anstatt sich auf latest zu verlassen.
Zweitens, wo die Modelldaten gespeichert werden sollen. Die offizielle Dokumentation mountet ein Volume auf /root/.ollama, damit Modelle nicht jedes Mal heruntergeladen werden müssen, wenn der Container ersetzt wird.
Hier ist eine Compose-Datei, die diese Entscheidungen einbaut und die „Regler" in der Nähe des Dienstes hält:
services:
ollama:
image: ollama/ollama:${OLLAMA_IMAGE_TAG:-latest}
container_name: ollama
restart: unless-stopped
# Standardmäßig lokal belassen, bei Bedarf später freigeben.
ports:
- "${OLLAMA_BIND_IP:-127.0.0.1}:11434:11434"
# Persistente Modelle und Server-Zustand.
volumes:
- ollama:/root/.ollama
environment:
# Das offizielle Image defaultet bereits auf 0.0.0.0:11434 innerhalb des Containers,
# aber es explizit zu halten hilft, wenn man Dinge später überschreibt.
- OLLAMA_HOST=0.0.0.0:11434
# Service-Einstellungen.
- OLLAMA_KEEP_ALIVE=${OLLAMA_KEEP_ALIVE:-5m}
- OLLAMA_NUM_PARALLEL=${OLLAMA_NUM_PARALLEL:-1}
- OLLAMA_MAX_LOADED_MODELS=${OLLAMA_MAX_LOADED_MODELS:-1}
# Optional, aber relevant, wenn eine browserbasierte UI direkt mit Ollama spricht.
# Siehe den Networking-Abschnitt für die Erklärung, warum das existiert.
- OLLAMA_ORIGINS=${OLLAMA_ORIGINS:-}
# GPU-Reservierung ist ein separater Abschnitt unten.
# Fügen Sie dies nur auf Hosts hinzu, die tatsächlich NVIDIA-GPUs haben.
volumes:
ollama: {}
Eine passende .env hält Upgrades langweilig:
# Fixieren Sie die Image-Version, die Sie getestet haben.
OLLAMA_IMAGE_TAG=latest
# Standardmäßig lokal. Auf 0.0.0.0 ändern, wenn Sie es bewusst freigeben.
OLLAMA_BIND_IP=127.0.0.1
# Keep-alive justiert die Kaltsstart-Latenz gegen den Speicherbedarf.
OLLAMA_KEEP_ALIVE=5m
# Parallelitäts-Regler.
OLLAMA_NUM_PARALLEL=1
OLLAMA_MAX_LOADED_MODELS=1
# Leer lassen, es sei denn, Sie bedienen Browser-Clients, die Ollama direkt aufrufen.
OLLAMA_ORIGINS=
Ein kleiner, aber wichtiger Feinunterschied: Ollama selbst hat in der allgemeinen Konfiguration eine Standard-Bindung an 127.0.0.1:11434, aber das offizielle Container-Image setzt OLLAMA_HOST=0.0.0.0:11434, damit der Dienst über freigegebene Ports erreichbar ist.
Wenn Sie eine schnelle Plausibilitätsprüfung ohne Einbeziehung von Client-SDKs wünschen, enthält die Ollama-API einen „lokale Modelle auflisten"-Endpunkt unter GET /api/tags.
Persistente Modellspeicherung und der schmerzärmste Weg, sie zu verschieben
Wenn Sie sich nur eine Sache merken sollen, dann diese: Der Container muss persistenten Speicher haben, andernfalls ist jeder Rebuild ein neues Herunterladen.
Ollama ermöglicht es Ihnen, das Modellverzeichnis mit OLLAMA_MODELS zu wählen. In der Referenzimplementierung ist der Standard $HOME/.ollama/models, und das Setzen von OLLAMA_MODELS überschreibt dies.
Innerhalb des offiziellen Docker-Images mappt $HOME natürlich auf das /root-Layout, das vom dokumentierten Volume-Mount (/root/.ollama) verwendet wird, was genau der Grund ist, warum die offiziellen docker run-Beispiele dieses Verzeichnis mounten.
Es gibt zwei Speichermuster, die in der Praxis gut funktionieren:
Ein benanntes Docker-Volumen ist am einfachsten und portabel. Es ist auch leicht versehentlich zu verwaissen, daher lohnt es sich, es bewusst zu benennen (z. B. ollama) und es über Compose-Refactorings stabil zu halten.
Ein Bind-Mount auf eine dedizierte Festplatte ist besser, wenn die Modellgrößen beginnen, Ihr Root-Dateisystem zu dominieren. In diesem Fall mounten Sie entweder das gesamte /root/.ollama auf diese Platte, oder Sie mounten ein benutzerdefiniertes Verzeichnis und weisen OLLAMA_MODELS darauf.
Wenn Sie Speicher aktiv neu organisieren, hilft hier ein explizites „Modelle verschieben"-Playbook. Siehe: move-ollama-models .
NVIDIA-GPU-Unterstützung mit Compose und dem NVIDIA Container Toolkit
Ollama kann NVIDIA-GPUs in Docker nutzen, aber das Image kann keine GPU aus dem Nichts zaubern. Der Host benötigt funktionierende NVIDIA-Treiber und das NVIDIA Container Toolkit, und Docker muss so konfiguriert sein, dass er es verwendet. Die Ollama-Docker-Dokumentation weist ausdrücklich auf die Installation von nvidia-container-toolkit, die Konfiguration des Runtime über nvidia-ctk runtime configure --runtime=docker und den Neustart von Docker hin.
Auf der Compose-Seite ist die saubere, moderne Art die Geräte-Reservierung. Docker dokumentiert GPU-Zugriff in Compose über deploy.resources.reservations.devices, mit capabilities: [gpu], driver: nvidia und entweder count (einschließlich all) oder device_ids.
Fügen Sie dies dem ollama-Service hinzu, wenn Sie auf einem NVIDIA-Host sind:
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
Wenn Sie mehrere GPUs haben und Ollama auf bestimmten Geräten halten möchten, wechseln Sie von count zu device_ids, wie von Docker dokumentiert (sie schließen sich gegenseitig aus).
Manchmal sieht man veraltete Compose-Beispiele, die runtime: nvidia verwenden. Das kann in neueren Setups zu Fehlern wie „unknown or invalid runtime name: nvidia" führen, was ein starker Hinweis ist, dass Sie zum unterstützten Geräte-Reservierungsmuster wechseln sollten und sicherstellen, dass das Toolkit auf dem Host konfiguriert ist.
Ein nützliches Detail, das auf der Oberfläche liegt: Das offizielle ollama/ollama-Image setzt NVIDIA_VISIBLE_DEVICES=all und NVIDIA_DRIVER_CAPABILITIES=compute,utility. Dies sind standardmäßige Regler, die vom NVIDIA-Container-Runtime erkannt werden, und sie sind bereits vorhanden, es sei denn, Sie überschreiben sie.
Um zu bestätigen, ob Sie tatsächlich GPU-Inferenz erhalten (und nicht nur einen Container, der startet), empfiehlt Ollama die Verwendung von ollama ps und das Prüfen der „Processor"-Spalte, die anzeigt, ob das Modell im GPU-Speicher ist.
Plattform-Realitätscheck: Ollama vermerkt, dass GPU-Beschleunigung in Docker unter Linux (und Windows mit WSL2) verfügbar ist, aber unter Docker Desktop für macOS aufgrund des Fehlens von GPU-Passthrough nicht verfügbar ist.
Networking-Optionen: host vs. bridge, Ports und CORS
Networking ist der Bereich, in dem die meisten „es läuft, aber meine App kann sich nicht verbinden"-Bugs herkommen.
Bridge-Netzwerk mit freigegebenen Ports
Das Standard-Compose-Netzwerk ist ein Bridge-Netzwerk. In diesem Setup macht das Freigeben von 11434:11434 Ollama vom Host aus auf Port 11434 erreichbar, während andere Container sich mit ihm über den Servicenamen ollama (nicht localhost) unterhalten sollten. Viele stolpern darüber, weil localhost innerhalb eines Containers „diesen Container" bedeutet, nicht „den Ollama-Container".
Ollama selbst führt einen HTTP-Server auf Port 11434 (das Image stellt ihn bereit), und die gängige Konvention ist, dass Clients http://localhost:11434 auf dem Host verwenden, wenn Ports freigegeben sind.
Host-Netzwerk
network_mode: host kann auf einem Single-Node-Server verlockend sein, weil es das Port-Freigeben entfernt und die localhost-Semantik vereinfacht. Der Nachteil ist, dass Sie die Isolations- und Namensraum-Vorteile eines Bridge-Netzwerks verlieren und eher auf Port-Konflikte stoßen.
Ollama bewusst freigeben
Ollama bindet bei einer normalen Installation standardmäßig an 127.0.0.1, und der dokumentierte Weg, die Bindungsadresse zu ändern, ist OLLAMA_HOST.
In Docker haben Sie zwei Ebenen:
Ollama-Bindungsadresse, kontrolliert durch OLLAMA_HOST (das Container-Image bindet standardmäßig an alle Schnittstellen innerhalb des Containers).
Erreichbarkeit von außerhalb des Containers, kontrolliert durch Compose ports und die Host-Firewall.
Ein Muster, das ich mag, ist „standardmäßig lokal binden" über 127.0.0.1:11434:11434 und dann nur zu 0.0.0.0:11434:11434 wechseln, wenn ich einen Grund habe, es freizugeben.
Browser-Clients und OLLAMA_ORIGINS
Wenn eine browserbasierte UI oder Erweiterung Ollama direkt aufruft, befinden Sie sich im CORS-Territorium. Ollama erlaubt standardmäßig Cross-Origin-Anfragen von 127.0.0.1 und 0.0.0.0, und Sie können zusätzliche Origins mit OLLAMA_ORIGINS konfigurieren.
Dies ist auch auf einem Single-Node wichtig, denn „es funktioniert mit curl" bedeutet nicht „es funktioniert aus einer Browser-App".
Upgrade- und Rollback-Muster, die zu einem Single-Node-Server passen
Ollama entwickelt sich schnell weiter. Ihre Compose-Datei kann daraus einen ruhigen Prozess machen, statt einer nächtlichen Überraschung.
Upgrade durch Bumpen eines Tags, nicht durch die Hoffnung, dass „latest" funktioniert
Die praktischste Upgrade-Strategie besteht darin, das Image in der .env auf ein bekannt gut funktionierendes Tag festzulegen und es bewusst zu erhöhen. Das Image wird auf Docker Hub als ollama/ollama veröffentlicht.
Da Modelldaten und Server-Zustand unter einem mounted Verzeichnis (in der offiziellen Dokumentation /root/.ollama) gespeichert werden, impliziert das Ersetzen des Containers kein erneutes Herunterladen der Modelle.
Rollback ist einfach das Zurückwechseln des Tags
Rollback ist derselbe Mechanismus in umgekehrter Richtung: Setzen Sie das vorherige Tag, erstellen Sie den Container neu, behalten Sie dasselbe Volume. Hier zahlt sich das Festpinnen aus.
Datenmigration dreht sich meist um Speicherpfade
Die meisten „Migrationen" in einem Single-Node-Setup drehen sich nicht um Datenbankschemata. Sie drehen sich um das Festplattenlayout. Wenn Sie das Modellverzeichnis ändern (über OLLAMA_MODELS) oder das mounted Volume auf eine neue Festplatte verschieben, führen Sie eine Datenmigration durch, ob Sie es so nennen oder nicht.
Wenn Sie einen praktischen Guide zum Neuorganisieren des Modellverzeichnisses auf echten Maschinen wünschen, siehe: move-ollama-models .
Ein abschließender Hinweis, der leicht übersehen wird: Die API-Dokumentation von Ollama sagt ausdrücklich, dass die API als stabil und abwärtskompatibel erwartet wird, mit seltenen Deprecations, die in den Release Notes angekündigt werden. Das macht „Server upgraden, Clients funktionieren lassen" zu einer vernünftigen Standarderwartung für einen Single-Node-Service-Endpunkt.
Häufige Fehler: GPU-Berechtigungen, Treiberunvereinbarkeit und OOM
Dieser Abschnitt ist bewusst symptomgetrieben. Das Ziel ist nicht „jeder mögliche Docker-Fehler", sondern nur die Fehler, die spezifisch in Ollama + GPU + persistenter Speicher-Setups auftreten.
GPU auf dem Host sichtbar, im Container fehlend
Wenn der Host einen funktionierenden NVIDIA-Treiber hat, aber der Container keine GPU sieht, sind die häufigen Ursachen:
Das NVIDIA Container Toolkit ist nicht installiert oder der Docker-Runtime ist nicht über nvidia-ctk konfiguriert. Die Ollama-Docker-Dokumentation weist dies direkt hin.
Compose reserviert kein GPU-Gerät. Der unterstützte Weg ist deploy.resources.reservations.devices mit der gpu-Fähigkeit, wie von Docker dokumentiert.
Eine veraltete runtime: nvidia-Konfiguration wird auf einem Daemon verwendet, der sie nicht erkennt, was „unknown or invalid runtime name: nvidia" erzeugt.
Zur Validierung gibt ollama ps einen pragmatischen Check: Es zeigt, ob ein Modell im GPU-Speicher geladen ist.
Berechtigung verweigert auf GPU-Geräten
Die „permission denied"-Variante von GPU-Fehlern deutet typischerweise auf Umgebungsbeschränkungen hin, nicht auf Ollama selbst. Beispiele umfassen Rootless-Docker, Sicherheitsrichtlinien oder Geräteknoten, die nicht wie erwartet freigegeben werden. Die Docker Compose GPU-Unterstützungsdokumentation stellt klar, dass der Host GPU-Geräte haben muss und dass der Docker-Daemon entsprechend eingerichtet sein muss.
Im Zweifel die Variablen reduzieren: Bestätigen Sie die Toolkit-Konfiguration (Host), dann bestätigen Sie die GPU-Reservierung (Compose), dann bestätigen Sie die GPU-Nutzung (ollama ps).
Falscher Treiber, falsche Erwartung
Ollama in Docker stützt sich auf den Host-Treiber-Stack. Wenn der Host-Treiber fehlt, zu alt ist oder falsch konfiguriert ist, sehen Sie Fehler, die aussehen wie „Ollama ist kaputt", aber tatsächlich bedeuten „CUDA-Stack ist nicht nutzbar". Die offizielle Dokumentation stellt das Container-Toolkit und die Docker-Daemon-Konfiguration als Voraussetzungen für die NVIDIA-GPU-Nutzung auf.
Speicherplatzmangel: VRAM oder RAM verschwindet schnell
OOM (Out of Memory) ist der vorhersehbarste Fehlermodus für lokale Inferenz, und er ist meist durch Konfiguration selbstverschuldet.
Ollama unterstützt parallele Verarbeitung durch mehrere geladene Modelle und parallele Anfrageverarbeitung, ist aber durch den verfügbaren Speicher begrenzt (System-RAM bei CPU-Inferenz, VRAM bei GPU-Inferenz). Wenn GPU-Inferenz verwendet wird, müssen neue Modelle in den VRAM passen, um parallele Modell-Ladevorgänge zu ermöglichen.
Zwei Konfigurationsdetails sind es wert, als erste-Klasse-„Server-Einstellungen" behandelt zu werden:
OLLAMA_NUM_PARALLEL erhöht die parallele Anfrageverarbeitung pro Modell, aber der benötigte Speicher skaliert mit OLLAMA_NUM_PARALLEL * OLLAMA_CONTEXT_LENGTH.
OLLAMA_KEEP_ALIVE steuert, wie lange Modelle geladen bleiben (Standard ist 5 Minuten). Das Halten von Modellen geladen reduziert Kaltsstart-Latenz, bindet aber auch Speicher.
Wenn Sie einen Single-Node-Service unter Last stabilisieren, sehen die dramenfreien Fixes meist so aus:
Parallellität und Kontext-Defaults senken, bevor Sie etwas anderes ändern.
Einschränken, wie viele Modelle gleichzeitig geladen bleiben dürfen.
In Erwägung ziehen, Speicher-Reduzierungsfunktionen wie Flash Attention (OLLAMA_FLASH_ATTENTION=1) und niedrigere Präzisions-K/V-Cache-Typen (OLLAMA_KV_CACHE_TYPE) zu verwenden, wenn Ihr Flaschenhals Speicher und nicht Rohrechenleistung ist.
Wenn es nicht Ollama ist: Docker Model Runner wählen
Manchmal ist der „Fehler" tatsächlich ein Werkzeug-Mismatch. Wenn Ihr Unternehmen bereits auf Docker-native Artefakte und Workflows standardisiert, kann Docker Model Runner (DMR) eine bessere Wahl sein als Ollama als langlebiger Service-Container zu betreiben.
Docker positioniert DMR als eine Art, Modelle direkt über Docker zu verwalten, auszuführen und bereitzustellen, gezogen von Docker Hub oder anderen OCI-Registries, und liefert OpenAI-kompatible und Ollama-kompatible APIs.
Es unterstützt auch mehrere Inferenz-Engines (einschließlich llama.cpp und vLLM auf Linux mit NVIDIA-GPUs), was wichtig sein kann, wenn Ihnen Durchsatz-Charakteristiken wichtig sind, nicht nur „ein Modell lokal ausführen".
Wenn Sie eine praktische Befehlsreferenz und einen tieferen Vergleichswinkel wünschen, siehe: Docker Model Runner Cheatsheet: Befehle & Beispiele.