Ollama i Docker Compose med GPU och bestående modelllagring

Ollama-server med komposition i förgrunden, GPU och uthållighet.

Sidinnehåll

Ollama fungerar utmärkt på “bare metal”. Det blir ännu mer intressant när du behandlar det som en tjänst: en stabil slutpunkt, fastlagda versioner, beständig lagring och en GPU som antingen är tillgänglig eller inte.

Detta inlägg fokuserar på ett mål: en återanvändbar lokal eller enskild nod “server” för Ollama med Docker Compose, med GPU-acceleration och beständig lagring av modeller.

ollama docker compose

Det medvetet hoppar över generella Docker- och Compose-basiska delar. När du behöver en kompakt lista över de kommandon du använder oftast (bilder, behållare, volymer, docker compose), är Docker Cheatsheet en bra följeslagare.

När du vill ha HTTPS framför Ollama, korrekt strömmande och WebSocket-proxynsättning, samt kantkontroller (autentisering, tidsgränser, hastighetsbegränsningar), se Ollama bakom en omvänd proxy med Caddy eller Nginx för HTTPS-strömmande.

För hur Ollama passar sig bredvid vLLM, Docker Model Runner, LocalAI och molnhostningens för- och nackdelar, se LLM-hosting 2026: Lokalt, Self-Hosted & Molninfrastruktur jämfört.

När Compose vinner mot en installation på “bare metal”

En nativ installation är friktionsfri för en utvecklare på en maskin. Men när du har något av följande, börjar Compose vinna när det gäller ergonomi:

Ett teamuppsättning gynnas eftersom tjänstdefinitionen är en fil som kan granskas, versioneras och delas. En enskild nodserver gynnas eftersom uppdateringar blir en bildtag-bump och en omstart, medan din modelllagring stannar kvar (så länge det finns på en volym). Ollama tenderar också att leva bredvid sidecars: en webbgränssnitt, en omvänd proxy, en autentiseringsport, en vektor-databas eller en agent-runtime. Compose är bra på “ett kommando för att starta hela stacken”, utan att göra din värdmaskin till en snowflake.

Detta tillvägagångssätt stämmer väl överens med hur den officiella Ollama-behållaren är designad: bilden kör ollama serve som standard, exponerar port 11434 och menas att hålla tillstånd under en monterbar katalog.

En Compose-skelett som faktiskt är användbar för Ollama

Börja med två beslut:

Först, hur du fastlägger versioner. Docker Hub-bilden är ollama/ollama, så du kan fastlägga en specifik tagg i .env istället för att lita på latest.

För det andra, var modelldata ska bo. De officiella dokumenten monterar en volym till /root/.ollama så att modeller inte laddas ner igen varje gång behållaren byts ut.

Här är en Compose-fil som bakar in dessa beslut och håller “knapparna” nära tjänsten:

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

    # Håll den lokal som standard, exponera den senare om du behöver.
    ports:
      - "${OLLAMA_BIND_IP:-127.0.0.1}:11434:11434"

    # Beständiga modeller och servertillstånd.
    volumes:
      - ollama:/root/.ollama

    environment:
      # Den officiella bilden har redan som standard 0.0.0.0:11434 inuti behållaren,
      # men att hålla den explicit hjälper när du skriver över saker senare.
      - OLLAMA_HOST=0.0.0.0:11434

      # Tjänstjusteringar.
      - OLLAMA_KEEP_ALIVE=${OLLAMA_KEEP_ALIVE:-5m}
      - OLLAMA_NUM_PARALLEL=${OLLAMA_NUM_PARALLEL:-1}
      - OLLAMA_MAX_LOADED_MODELS=${OLLAMA_MAX_LOADED_MODELS:-1}

      # Valfritt, men relevant när ett webbläsarbaserat gränssnitt pratar direkt med Ollama.
      # Se nätverksavsnittet för varför detta finns.
      - OLLAMA_ORIGINS=${OLLAMA_ORIGINS:-}

    # GPU-reservation är ett separat avsnitt nedan.
    # Lägg till den bara på värdar som faktiskt har NVIDIA-GPU:er.

volumes:
  ollama: {}

En matchande .env håller uppdateringar tråkiga:

# Fastligger bildversionen du har testat.
OLLAMA_IMAGE_TAG=latest

# Lokal som standard. Ändra till 0.0.0.0 när du medvetet exponerar den.
OLLAMA_BIND_IP=127.0.0.1

# Keep-alive justeringar för kallstartslatens mot minnesfotavtryck.
OLLAMA_KEEP_ALIVE=5m

# Konkurrensknapar.
OLLAMA_NUM_PARALLEL=1
OLLAMA_MAX_LOADED_MODELS=1

# Lämna tom såvida du inte serverar webbläsarklienter som träffar Ollama direkt.
OLLAMA_ORIGINS=

En liten men viktig nyans: Ollama har som standard en värdbindning på 127.0.0.1:11434 i den generella konfigurationen, men den officiella behållar-bilden sätter OLLAMA_HOST=0.0.0.0:11434 så att tjänsten är nåbar genom publicerade portar.

Om du vill ha en snabb kontroll utan att involvera några klient-SDK:er, inkluderar Ollama-API:t en “lista lokala modeller”-slutpunkt på GET /api/tags.

Beständig modelllagring och det minst smärtsamma sättet att flytta den

Om du bara minns en sak, låt det vara detta: behållaren måste ha beständig lagring, annars är varje ombyggnad en ominladdning.

Ollama låter dig välja modellkatalogen med OLLAMA_MODELS. I referensimplementeringen är standarden $HOME/.ollama/models, och att sätta OLLAMA_MODELS skriver över det.

Inuti den officiella Docker-bilden mappar $HOME naturligt till /root-layouten som används av den dokumenterade volymmontaget (/root/.ollama), vilket är exakt varför de officiella docker run-exemplen monterar den katalogen.

Det finns två lagringsmönster som tenderar att fungera väl i praktiken:

En namngiven Docker-volym är enklast och portabel. Det är också lätt att av misstag orfana, så det är värt att namnge den medvetet (till exempel ollama) och hålla den stabil över Compose-refaktoriseringar.

En bind-mount till en dedikerad disk är bättre när modellstorlekar börjar dominera ditt rotfilssystem. I det fallet monterar du antingen hela /root/.ollama till den disken, eller så monterar du en anpassad katalog och pekar OLLAMA_MODELS mot den.

Om du aktivt omorganiserar lagring är det här en explicit “flytta modeller”-spelplan hjälper. Se: move-ollama-models .

NVIDIA GPU-stöd med Compose och NVIDIA Container Toolkit

Ollama kan använda NVIDIA-GPU:er i Docker, men bilden kan inte trolla fram en GPU. Värdmaskinen behöver fungerande NVIDIA-drivrutiner och NVIDIA Container Toolkit, och Docker måste konfigureras att använda det. Ollamas Docker-dokumentation pekar ut explicit installation av nvidia-container-toolkit, konfiguration av runtime via nvidia-ctk runtime configure --runtime=docker, och omstart av Docker.

På Compose-sidan är det rena, moderna sättet enhetsreservationer. Docker dokumenterar GPU-tillgång i Compose med deploy.resources.reservations.devices, med capabilities: [gpu], driver: nvidia, och antingen count (inklusive all) eller device_ids.

Lägg till detta till ollama-tjänsten när du är på en NVIDIA-värd:

deploy:
  resources:
    reservations:
      devices:
        - driver: nvidia
          count: all
          capabilities: [gpu]

Om du har flera GPU:er och vill hålla Ollama på specifika enheter, byt från count till device_ids enligt Docker-dokumentationen (de är ömsesidigt uteslutande).

Du kommer ibland att se äldre Compose-exempel som använder runtime: nvidia. Det kan misslyckas på nyare installationer med fel som “unknown or invalid runtime name: nvidia”, vilket är en stark hint att du bör flytta till det stödda mönstret för enhetsreservation och se till att toolkit är konfigurerat på värdmaskinen.

En användbar detalj som gömmer sig i plain sight: den officiella ollama/ollama-bilden sätter NVIDIA_VISIBLE_DEVICES=all och NVIDIA_DRIVER_CAPABILITIES=compute,utility. Dessa är standardknappar som erkänns av NVIDIA-behållar-runtime, och de finns redan med såvida du inte skriver över dem.

För att bekräfta att du faktiskt får GPU-inferens (inte bara en behållare som startar), rekommenderar Ollama att använda ollama ps och kolla “Processor”-kolumnen, som visar om modellen är i GPU-minnet.

Plattform-reality check: Ollama noterar att GPU-acceleration i Docker är tillgänglig på Linux (och Windows med WSL2), och inte tillgänglig på Docker Desktop för macOS på grund av avsaknad av GPU-passthrough.

Nätverksval: värd vs bro, portar och CORS

Nätverk är där de flesta “det kör men min app kan inte ansluta”-buggar kommer ifrån.

Bronätverk med publicerade portar

Default Compose-nätverk är ett bronätverk. I denna uppsättning gör publicering av 11434:11434 att Ollama är nåbar från värdmaskinen på port 11434, medan andra behållare bör prata med den med tjänstnamnet ollama (inte localhost). Många trippar på detta eftersom localhost inuti en behållare betyder “den här behållaren”, inte “Ollama-behållaren”.

Ollama kör själv en HTTP-server på port 11434 (bilden exponerar den), och den vanliga konventionen är att klienter använder http://localhost:11434 på värdmaskinen när portar är publicerade.

Värdnätverk

network_mode: host kan vara lockande på en enskild nodserver eftersom det tar bort portpublicering och gör localhost-semantiken enklare. Priset är att du förlorar isolerings- och namnrymdsfördelarna med ett bronätverk, och du är mer sannolikt att stöta på portkonflikter.

Att medvetet exponera Ollama

Ollama på en vanlig installation binder till 127.0.0.1 som standard, och den dokumenterade vägen att ändra bindningsadressen är OLLAMA_HOST.

I Docker har du två lager:

Ollama-bindningsadress, kontrollerad av OLLAMA_HOST (behållar-bilden har som standard bindning på alla gränssnitt inuti behållaren).

Nåbarhet utanför behållaren, kontrollerad av Compose ports och värdmaskinens brandvägg.

Ett mönster jag gillar är “binda lokalt som standard” via 127.0.0.1:11434:11434, och sedan byta till 0.0.0.0:11434:11434 bara när jag har en anledning att exponera det.

Webbläsarklienter och OLLAMA_ORIGINS

Om ett webbläsarbaserat gränssnitt eller tillägg anropar Ollama direkt, är du i CORS-territorium. Ollama tillåter korsdomänförfrågningar från 127.0.0.1 och 0.0.0.0 som standard, och du kan konfigurera ytterligare ursprung med OLLAMA_ORIGINS.

Detta spelar roll även på en enskild nod, eftersom “det fungerar med curl” inte betyder “det fungerar från en webbläsarapp”.

Uppgraderings- och rollbackmönster som passar en enskild nodserver

Ollama utvecklas snabbt. Din Compose-fil kan göra det till en lugn process istället för en sent-nattsuppvakning.

Uppgradera genom att bumpa en tagg, inte genom att hoppas att “latest” beter sig

Den mest praktiska uppgraderingsstrategin är att fastlägga bilden till en känd bra tagg i .env, och bumpa den medvetet. Bilden publiceras som ollama/ollama på Docker Hub.

Eftersom modelldata och servertillstånd lagras under en monterad katalog (/root/.ollama i de officiella dokumenten), innebär inte att byta ut behållaren att ominladda modeller.

Rollback är bara att byta tagg tillbaka

Rollback är samma mekanism i omvänd riktning: sätt den tidigare taggen, återskapa behållaren, behåll samma volym. Det är här fastläggen betalar sig själv.

Datamigration handlar mest om lagringsvägar

De flesta “migrationer” i en enskild noduppsättning handlar inte om databasscheman. De handlar om disklayout. Om du ändrar modellkatalogen (via OLLAMA_MODELS) eller flyttar den monterade volymen till en ny disk, gör du en datamigration oavsett om du kallar det så eller inte.

Om du vill ha en praktisk guide för att omorganisera modellkatalogen på verkliga maskiner, se: move-ollama-models .

En sista notis som är lätt att missa: Ollamas API-dokumentation säger explicit att API:t förväntas vara stabilt och bakåtkompatibel, med sällsynta nedskrivningar som annonseras i releaseanteckningar. Det gör “uppgradera servern, håll klienter fungerande” en rimlig standardförväntning för en enskild nodtjänstslutpunkt.

Vanliga misslyckanden: GPU-behörigheter, drivrutinsmismatch och OOM

Detta avsnitt är medvetet symtomdrivet. Målet är inte “varje möjlig Docker-fel”, bara de misslyckanden som uppstår specifikt i Ollama + GPU + beständig lagringsuppsättningar.

GPU synlig på värdmaskinen, saknas i behållaren

Om värdmaskinen har en fungerande NVIDIA-drivrutin men behållaren inte ser en GPU, är de vanliga orsakerna:

NVIDIA Container Toolkit är inte installerat eller Docker-runtime är inte konfigurerad via nvidia-ctk. Ollamas Docker-dokumentation pekar ut detta direkt.

Compose reserverar inte en GPU-enhet. Det stödda sättet är deploy.resources.reservations.devices med gpu-kapabiliteten enligt Docker-dokumentationen.

En legacy runtime: nvidia-konfiguration används på en daemon som inte känner igen den, vilket producerar “unknown or invalid runtime name: nvidia”.

För validering ger ollama ps dig en pragmatisk kontroll: det visar om en modell är laddad i GPU-minnet.

Behörighet nekad på GPU-enheter

“Permission denied”-smaken av GPU-misslyckanden pekar oftast på miljöbegränsningar snarare än Ollama själv. Exempel inkluderar körning av rootless Docker, säkerhetspolicyer, eller att enhetsnoder inte exponeras som förväntat. Docker Compose GPU-stöddokumentationen är explicit om att värdmaskinen måste ha GPU-enheter och att Docker-daemonen måste ställas in därefter.

När du är osäker, minska variablerna: bekräfta toolkit-konfigurationen (värdmaskin), sedan bekräfta GPU-reservation (Compose), sedan bekräfta GPU-användning (ollama ps).

Fel drivrutin, fel förväntan

Ollama i Docker litar på värdmaskinens drivrutinstack. Om värdmaskinens drivrutin saknas, är för gammal eller felkonfigurerad, kommer du att se misslyckanden som ser ut som “Ollama är trasig” men egentligen är “CUDA-stacken är inte användbar”. De officiella dokumenten placerar behållar-toolkiten och Docker-daemon-konfigurationen som förutsättningar för NVIDIA GPU-användning.

Minnet är slut: VRAM eller RAM försvinner snabbt

OOM är det mest förutsägbara misslyckandet för lokal inferens, och det är oftast självförorsakat av konfiguration.

Ollama stöder koncurrent bearbetning genom flera laddade modeller och parallell förfråghantering, men det är begränsat av tillgängligt minne (systemminne på CPU-inferens, VRAM på GPU-inferens). När GPU-inferens används måste nya modeller passa i VRAM för att tillåta koncurrent modellladdning.

Två konfigurationsdetaljer är värt att behandla som förstaklassiga “serverinställningar”:

OLLAMA_NUM_PARALLEL ökar parallell förfråganbearbetning per modell, men kravet på minne skalar med OLLAMA_NUM_PARALLEL * OLLAMA_CONTEXT_LENGTH.

OLLAMA_KEEP_ALIVE kontrollerar hur länge modeller förblir laddade (standard är 5 minuter). Att hålla modeller laddade minskar kallstartslatens, men det låser också minnet.

Om du stabiliserar en enskild nodtjänst under belastning, ser de icke-dramatiska fixarna oftast ut som:

Sänk parallelism och kontextstandarder innan du ändrar något annat.

Begränsa hur många modeller som får förbli laddade samtidigt.

Överväg minnesreducerande funktioner som Flash Attention (OLLAMA_FLASH_ATTENTION=1) och lägre precision K/V-cache-typer (OLLAMA_KV_CACHE_TYPE) när din flaskhals är minne, inte rå beräkning.

När det inte är Ollama: välja Docker Model Runner istället

Ibland är “misslyckandet” egentligen ett verktygsmismatch. Om din organisation redan standardiserar på Docker-inriktade artefakter och arbetsflöden, kan Docker Model Runner (DMR) vara ett bättre val än att köra Ollama som en långlivad behållartjänst.

Docker positionerar DMR som ett sätt att hantera, köra och servera modeller direkt via Docker, draga från Docker Hub eller andra OCI-registren, och servera OpenAI-kompatibla och Ollama-kompatibla API:er.

Det stöder också flera inferensmotorer (inklusive llama.cpp, och vLLM på Linux med NVIDIA-GPU:er), vilket kan spela roll om du bryr dig om igenomströmningsegenskaper, inte bara “kör en modell lokalt”.

Om du vill ha en praktisk kommandoreferens och ett djupare jämförelseperspektiv, se: Docker Model Runner Cheatsheet: Kommandon & Exempel.