Ollama in Docker Compose mit GPU und persistenter Modell-Speicherung

Compose-first Ollama-Server mit GPU und Persistenz.

Inhaltsverzeichnis

Ollama funktioniert hervorragend auf Bare Metal. Es wird noch interessanter, wenn man es wie einen Service behandelt: ein stabiler Endpunkt, fixierte Versionen, persistente Speicherung und eine GPU, die entweder verfügbar ist oder eben nicht.

Dieser Beitrag konzentriert sich auf ein einziges Ziel: einen reproduzierbaren lokalen oder Single-Node-Ollama-“Server” mit Docker Compose, GPU-Beschleunigung und persistenter Modellspeicherung.

ollama docker compose

Es werden bewusst generische Docker- und Compose-Grundlagen ausgelassen. Wenn Sie eine kompakte Liste der Befehle benötigen, zu denen Sie am häufigsten greifen (Images, Container, Volumes, docker compose), ist die Docker Cheatsheet ein guter Begleiter.

Wenn Sie HTTPS vor Ollama, korrekte Streaming- und WebSocket-Proxys sowie Edge-Steuerungen (Authentifizierung, Timeouts, Ratenlimits) wünschen, lesen Sie Ollama hinter einem Reverse Proxy mit Caddy oder Nginx für HTTPS-Streaming.

Wie Ollama im Vergleich zu vLLM, Docker Model Runner, LocalAI und den Trade-offs bei Cloud-Hosting passt, erfahren Sie unter LLM-Hosting im Jahr 2026: Lokal, Self-Hosted und Cloud-Infrastruktur im Vergleich.

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 puncto Ergonomie:

Eine Team-Einrichtung profitiert, da die Service-Definition eine Datei ist, die Sie überprüfen, versionieren und teilen können. Ein Single-Node-Server profitiert, da Upgrades zu einem Image-Tag-Update und einem Neustart werden, während Ihre Modellspeicherung erhalten bleibt (sofern sie auf einem Volume liegt). Ollama lebt zudem oft neben Sidecars: einer Web-UI, einem Reverse Proxy, einem Auth-Gateway, einer Vektor-Datenbank oder einem Agent-Runtime. Compose ist gut darin, “mit einem Befehl die gesamte Stack zu starten”, ohne den Host zu einem Schneeflocken zu machen.

Dieser Ansatz stimmt gut mit dem überein, wie das offizielle Ollama-Container-Image entworfen wurde: Das Image führt standardmäßig ollama serve aus, legt Port 11434 frei und ist darauf ausgelegt, den Zustand unter einem mountbaren Verzeichnis zu halten.

Ein Compose-Gerüst, das für Ollama wirklich nützlich ist

Beginnen Sie mit zwei Entscheidungen:

Erstens, wie Sie Versionen fixieren. Das Docker-Hub-Image ist ollama/ollama, sodass Sie ein bestimmtes Tag in .env fixieren können, anstatt sich auf latest zu verlassen.

Zweitens, wo die Modelldaten liegen sollen. Die offizielle Dokumentation mountet ein Volume auf /root/.ollama, sodass Modelle nicht jedes Mal neu heruntergeladen werden, wenn der Container ersetzt wird.

Hier ist eine Compose-Datei, die diese Entscheidungen einbaut und die “Stellschrauben” nah am Service hält:

services:
  ollama:
    image: ollama/ollama:${OLLAMA_IMAGE_TAG:-latest}
    container_name: ollama
    restart: unless-stopped

    # Standardmäßig lokal halten, später freigeben, falls benötigt.
    ports:
      - "${OLLAMA_BIND_IP:-127.0.0.1}:11434:11434"

    # Persistente Modelle und Serverzustand.
    volumes:
      - ollama:/root/.ollama

    environment:
      # Das offizielle Image verwendet standardmäßig 0.0.0.0:11434 im Container,
      # aber das Explizit-Halten hilft, wenn Sie später Dinge überschreiben.
      - OLLAMA_HOST=0.0.0.0:11434

      # Service-Tuning.
      - 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 Abschnitt Netzwerk, warum dies existiert.
      - OLLAMA_ORIGINS=${OLLAMA_ORIGINS:-}

    # Die GPU-Reservierung ist ein separater Abschnitt unten.
    # Hinzufügen nur auf Hosts, die tatsächlich NVIDIA-GPUs haben.

volumes:
  ollama: {}

Ein passendes .env hält Upgrades langweilig:

# Fixieren Sie die Image-Version, die Sie getestet haben.
OLLAMA_IMAGE_TAG=latest

# Standardmäßig lokal. Ändern Sie zu 0.0.0.0, wenn Sie es absichtlich freigeben.
OLLAMA_BIND_IP=127.0.0.1

# Keep-Alive-Anpassungen kalte Startlatenz vs. Speicherabdruck.
OLLAMA_KEEP_ALIVE=5m

# Parallelitäts-Stellschrauben.
OLLAMA_NUM_PARALLEL=1
OLLAMA_MAX_LOADED_MODELS=1

# Leer lassen, es sei denn, Sie bedienen Browser-Clients, die Ollama direkt ansprechen.
OLLAMA_ORIGINS=

Eine kleine, aber wichtige Nuance: Ollama selbst hat eine Standard-Host-Bindung von 127.0.0.1:11434 in der allgemeinen Konfiguration, aber das offizielle Container-Image setzt OLLAMA_HOST=0.0.0.0:11434, sodass der Service über veröffentlichte Ports erreichbar ist.

Wenn Sie eine schnelle Plausibilitätsprüfung ohne Beteiligung von Client-SDKs wünschen, enthält die Ollama-API einen Endpunkt “lokale Modelle auflisten” unter GET /api/tags.

Persistente Modellspeicherung und die schmerzloseste Art, sie zu verschieben

Wenn Sie sich nur eine Sache merken, dann diese: Der Container muss einen persistenten Speicher haben, sonst ist jeder Rebuild ein neuer Download.

Ollama lässt Sie das Modelldirectory über OLLAMA_MODELS wählen. In der Referenzimplementierung ist das Standard $HOME/.ollama/models, und das Setzen von OLLAMA_MODELS überschreibt dies.

Im offiziellen Docker-Image映射t $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 sich in der Praxis bewähren:

Ein benanntes Docker-Volume ist am einfachsten und portabel. Es ist jedoch leicht, es versehentlich zu verwaisen, daher lohnt es sich, es bewusst zu benennen (zum Beispiel ollama) und es über Compose-Refactorings hinweg 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 Festplatte oder Sie mounten ein benutzerdefiniertes Verzeichnis und zeigen OLLAMA_MODELS darauf.

Wenn Sie aktiv die Speicherung 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 entsprechend konfiguriert sein. Die Ollama-Docker-Dokumentation fordert explizit die Installation von nvidia-container-toolkit, die Konfiguration des Runtimes über nvidia-ctk runtime configure --runtime=docker und den Neustart von Docker.

Auf der Compose-Seite ist der saubere, moderne Weg die Geräte-Reservierung. Docker dokumentiert den 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 behalten wollen, wechseln Sie von count zu device_ids, wie von Docker dokumentiert (sie sind sich gegenseitig ausschließend).

Manchmal sieht man veraltete Compose-Beispiele, die runtime: nvidia verwenden. Das kann bei neueren Setups mit Fehlern wie “unknown or invalid runtime name: nvidia” fehlschlagen, was ein starker Hinweis ist, dass Sie zum unterstützten Geräte-Reservierungsmuster wechseln und sicherstellen sollten, dass das Toolkit auf dem Host konfiguriert ist.

Ein nützliches Detail, das vor lauter Augen verborgen ist: Das offizielle ollama/ollama-Image setzt NVIDIA_VISIBLE_DEVICES=all und NVIDIA_DRIVER_CAPABILITIES=compute,utility. Dies sind Standard-Stellschrauben, 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 (nicht nur ein Container, der startet), empfiehlt Ollama die Verwendung von ollama ps und die Überprüfung der Spalte “Processor”, die anzeigt, ob das Modell im GPU-Speicher liegt.

Plattform-Realitätscheck: Ollama stellt fest, dass GPU-Beschleunigung in Docker auf Linux (und Windows mit WSL2) verfügbar ist, aber auf Docker Desktop für macOS aufgrund fehlender GPU-Passthrough nicht verfügbar ist.

Netzwerkentscheidungen: host vs. bridge, Ports und CORS

Netzwerk ist der Ort, an dem die meisten “es läuft, aber meine App kann nicht verbinden”-Fehler entstehen.

Bridge-Netzwerk mit veröffentlichten Ports

Das Standard-Compose-Netzwerk ist ein Bridge-Netzwerk. In dieser Einrichtung macht das Veröffentlichen von 11434:11434 Ollama vom Host auf Port 11434 erreichbar, während andere Container mit ihm über den Servicenamen ollama (nicht localhost) sprechen sollten. Viele stolpern darüber, weil localhost innerhalb eines Containers “dieser Container” bedeutet, nicht “der Ollama-Container”.

Ollama selbst betreibt einen HTTP-Server auf Port 11434 (das Image legt ihn frei), und die übliche Konvention ist, dass Clients http://localhost:11434 auf dem Host verwenden, wenn Ports veröffentlicht sind.

Host-Netzwerk

network_mode: host kann auf einem Single-Node-Server verlockend sein, da es das Port-Veröffentlichen entfernt und die localhost-Semantik vereinfacht. Der Trade-off ist, dass Sie die Isolations- und Namespace-Vorteile eines Bridge-Netzwerks verlieren und häufiger auf Port-Konflikte stoßen.

Ollama absichtlich freigeben

Ollama bindet bei einer normalen Installation standardmäßig an 127.0.0.1, und der dokumentierte Weg, die Bind-Adresse zu ändern, ist OLLAMA_HOST.

In Docker haben Sie zwei Ebenen:

Ollama-Bind-Adresse, gesteuert durch OLLAMA_HOST (das Container-Image bindet standardmäßig an alle Schnittstellen innerhalb des Containers).

Erreichbarkeit von außerhalb des Containers, gesteuert 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 dann 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 über OLLAMA_ORIGINS konfigurieren.

Das ist sogar auf einem Single-Node relevant, weil “es funktioniert mit curl” nicht bedeutet “es funktioniert aus einer Browser-App”.

Upgrade- und Rollback-Muster, die für einen Single-Node-Server passen

Ollama entwickelt sich schnell. Ihre Compose-Datei kann dies zu einem ruhigen Prozess machen, anstatt zu einer Überraschung in der Nacht.

Upgrade durch Hochstufen eines Tags, nicht durch Hoffen, dass “latest” funktioniert

Die praktischste Upgrade-Strategie ist, das Image auf ein bekanntes gutes Tag in .env zu fixieren und es bewusst hochzustufen. Das Image wird auf Docker Hub als ollama/ollama veröffentlicht.

Da Modelldaten und Serverzustand unter einem gemounteten Verzeichnis gespeichert sind (/root/.ollama in der offiziellen Dokumentation), impliziert das Ersetzen des Containers nicht das Neu-Downloaden von Modellen.

Rollback ist nur das Zurückstellen 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 Fixieren aus.

Datenmigration dreht sich meist um Speicherpfade

Die meisten “Migrationen” in einer Single-Node-Einrichtung betreffen keine Datenbankschemata. Sie betreffen die Disk-Layouts. Wenn Sie das Modelldirectory ändern (über OLLAMA_MODELS) oder das gemountete Volume auf eine neue Festplatte verschieben, führen Sie eine Datenmigration durch, egal ob Sie es so nennen oder nicht.

Wenn Sie einen praktischen Leitfaden für die Neuordnung des Modelldirectorys auf echten Maschinen wünschen, lesen Sie: move-ollama-models .

Ein letzter Hinweis, der leicht übersehen wird: Die API-Dokumentation von Ollama besagt explizit, dass die API stabil und abwärtskompatibel erwartet wird, mit seltenen Deprecations, die in Release Notes angekündigt werden. Das macht “Server upgraden, Clients weiterlaufen lassen” zu einer vernünftigen Standarderwartung für einen Single-Node-Service-Endpunkt.

Häufige Fehler: GPU-Berechtigungen, Treiber-Mismatch 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 + persistente Speicher-Setups auftreten.

GPU auf dem Host sichtbar, im Container fehlend

Wenn der Host einen funktionierenden NVIDIA-Treiber hat, der Container jedoch keine GPU sieht, sind die häufigsten 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 darauf 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 zu “unknown or invalid runtime name: nvidia” führt.

Zur Validierung gibt ollama ps eine pragmatische Prüfung: Es zeigt, ob ein Modell im GPU-Speicher geladen ist.

Berechtigung verweigert bei GPU-Geräten

Die “Berechtigung verweigert”-Variante von GPU-Fehlern deutet typischerweise auf Umgebungsbeschränkungen hin, nicht auf Ollama selbst. Beispiele umfassen rootless Docker, Sicherheitsrichtlinien oder Geräte-Knoten, die nicht wie erwartet freigegeben werden. Die Docker-Compose-GPU-Unterstützungsdokumente sind explizit, dass der Host GPU-Geräte haben muss und dass der Docker-Daemon entsprechend eingestellt sein muss.

Im Zweifel reduzieren Sie die Variablen: 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 verlässt sich auf den Host-Treiber-Stack. Wenn der Host-Treiber fehlt, zu alt ist oder falsch konfiguriert ist, sehen Sie Fehler, die wie “Ollama ist kaputt” aussehen, aber eigentlich “CUDA-Stack ist nicht nutzbar” bedeuten. Die offizielle Dokumentation stellt das Container-Toolkit und die Docker-Daemon-Konfiguration als Voraussetzungen für die NVIDIA-GPU-Nutzung dar.

Speicherüberlauf: VRAM oder RAM verschwindet schnell

OOM ist das vorhersehbarste Fehlermuster für lokale Inferenz und wird in der Regel durch Konfiguration selbst verursacht.

Ollama unterstützt parallele Verarbeitung durch mehrere geladene Modelle und parallele Anfragebehandlung, ist jedoch 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 Modellladungen zu ermöglichen.

Zwei Konfigurationsdetails sollten als erste Klasse “Server-Einstellungen” behandelt 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 sind 5 Minuten). Modelle geladen zu halten, reduziert die Kaltstartlatenz, bindet aber auch Speicher.

Wenn Sie einen Single-Node-Service unter Last stabilisieren, sehen die nicht-dramatischen Fixes normalerweise so aus:

Senken Sie Parallelität und Kontext-Standardwerte, bevor Sie etwas anderes ändern.

Begrenzen Sie, wie viele Modelle gleichzeitig geladen bleiben dürfen.

Betrachten Sie Speicherreduktionsfunktionen wie Flash Attention (OLLAMA_FLASH_ATTENTION=1) und niedrigere Präzisions-K/V-Cache-Typen (OLLAMA_KV_CACHE_TYPE), wenn Ihr Flaschenhals Speicher und nicht rohe Rechenleistung ist.

Wenn es nicht Ollama ist: Docker Model Runner wählen

Manchmal ist der “Fehler” eigentlich ein Werkzeug-Mismatch. Wenn Ihre Organisation bereits auf Docker-native Artefakte und Workflows standardisiert, kann Docker Model Runner (DMR) eine bessere Wahl sein als Ollama als langlebigen Service-Container zu betreiben.

Docker positioniert DMR als eine Möglichkeit, Modelle direkt über Docker zu verwalten, auszuführen und bereitzustellen, wobei es von Docker Hub oder anderen OCI-Registries zieht und OpenAI-kompatible sowie Ollama-kompatible APIs bereitstellt.

Es unterstützt auch mehrere Inferenz-Engines (einschließlich llama.cpp und vLLM auf Linux mit NVIDIA-GPUs), was wichtig sein kann, wenn es Ihnen auf Durchsatzmerkmale ankommt, nicht nur darauf, “ein Modell lokal auszuführen”.

Wenn Sie eine praktische Befehlsreferenz und einen tieferen Vergleichswinkel wünschen, lesen Sie: Docker Model Runner Cheatsheet: Befehle & Beispiele.