Ollama w Docker Compose z obsługą GPU i trwałą pamięcią modeli
Serwer Ollama z pierwszeństwem kompozycji, obsługą GPU i trwałością danych.
Ollama świetnie działa na “gołym metalu”. Zyskuje jednak na ciekawości, gdy potraktujesz ją jako usługę: stabilny punkt końcowy, zablokowane wersje, trwałe przechowywanie danych oraz dostępność GPU, która jest albo dostępna, albo nie.
Ten post skupia się na jednym celu: odtwarzalnym, lokalnym lub jednowęzłowym “serwerze” Ollama przy użyciu Docker Compose, z przyspieszeniem GPU i trwałym przechowywaniem modeli.

Pomijamy celowo ogólne podstawy Docker i Compose. Gdy potrzebujesz zwięzłej listy najczęściej używanych poleceń (obrazy, kontenery, woluminy, docker compose), Skrótka Docker jest dobrym towarzyszem.
Jeśli chcesz użyć HTTPS przed Ollama, poprawnego przekazywania strumienia i proxy Websocket oraz kontrole krawędzowe (autoryzacja, limity czasu, limity przepływu), zobacz Ollama za proxy odwrotnym z Caddy lub Nginx do strumieniowania HTTPS.
Jeśli chcesz dowiedzieć się, jak Ollama współpracuje z vLLM, Docker Model Runner, LocalAI oraz kompromisami w chmurze, zobacz Hosting LLM w 2026 roku: Porównanie infrastruktury lokalnej, samohostowanej i chmurowej.
Kiedy Compose wygrywa z instalacją na “gołym metalu”
Natywna instalacja jest bezproblemowa dla jednego dewelopera na jednej maszynie. W momencie pojawienia się któregokolwiek z poniższych scenariuszy, Compose zaczyna wygrywać pod względem ergonomii:
Konfiguracja zespołu zyskuje, ponieważ definicja usługi jest plikiem, który można przeglądać, wersjonować i udostępniać. Serwer jednowęzłowy zyskuje, ponieważ aktualizacje sprowadzają się do zmiany tagu obrazu i restartu, podczas gdy dane modeli pozostają w miejscu (pod warunkiem, że są na woluminie). Ollama również ma tendencję do bycia obok usług dodatkowych: interfejsu webowego, proxy odwrotnego, bramki autoryzacyjnej, bazy wektorowej lub środowiska uruchomieniowego agentów. Compose jest dobry w “jednym poleceniu do uruchomienia całej stosu”, nie zamieniając przy tym hosta w płatka śniegu.
To podejście dobrze koresponduje z tym, jak zaprojektowany jest oficjalny kontener Ollama: obraz domyślnie uruchamia ollama serve, wystawia port 11434 i jest zaprojektowany tak, aby utrzymywać stan w katalogu montowanym.
Szkielet Compose, który jest naprawdę przydatny dla Ollama
Zacznij od dwóch decyzji:
Po pierwsze, jak zablokujesz wersje. Obraz na Docker Hub to ollama/ollama, więc możesz zablokować konkretny tag w .env, zamiast polegać na latest.
Po drugie, gdzie będą przechowywane dane modeli. Oficjalna dokumentacja sugeruje zamontowanie woluminu do /root/.ollama, aby modele nie były pobierane na nowo za każdym razem, gdy kontener jest zastępowany.
Oto plik Compose, który uwzględnia te decyzje i trzyma “sterowniki” blisko usługi:
services:
ollama:
image: ollama/ollama:${OLLAMA_IMAGE_TAG:-latest}
container_name: ollama
restart: unless-stopped
# Domyślnie lokalnie, wystaw później, jeśli to konieczne.
ports:
- "${OLLAMA_BIND_IP:-127.0.0.1}:11434:11434"
# Trwałe modele i stan serwera.
volumes:
- ollama:/root/.ollama
environment:
# Oficjalny obraz domyślnie używa 0.0.0.0:11434 wewnątrz kontenera,
# ale jawne podanie pomaga przy późniejszych nadpisaniami.
- OLLAMA_HOST=0.0.0.0:11434
# Tuning usługi.
- OLLAMA_KEEP_ALIVE=${OLLAMA_KEEP_ALIVE:-5m}
- OLLAMA_NUM_PARALLEL=${OLLAMA_NUM_PARALLEL:-1}
- OLLAMA_MAX_LOADED_MODELS=${OLLAMA_MAX_LOADED_MODELS:-1}
# Opcjonalne, ale istotne, gdy interfejs przeglądarkowy rozmawia bezpośrednio z Ollama.
# Zobacz sekcję Sieć, aby dowiedzieć się, dlaczego to istnieje.
- OLLAMA_ORIGINS=${OLLAMA_ORIGINS:-}
# Rezerwacja GPU to osobna sekcja poniżej.
# Dodaj tylko na hostach, które faktycznie mają karty NVIDIA.
volumes:
ollama: {}
Pasujący plik .env sprawia, że aktualizacje są nudne:
# Zablokuj wersję obrazu, którą przetestowałeś.
OLLAMA_IMAGE_TAG=latest
# Domyślnie lokalnie. Zmień na 0.0.0.0, gdy celowo chcesz to wystawić.
OLLAMA_BIND_IP=127.0.0.1
# Ustawienia keep-alive wpływają na opóźnienia zimnego startu vs. zapotrzebowanie na pamięć.
OLLAMA_KEEP_ALIVE=5m
# Sterowniki konkurencyjności.
OLLAMA_NUM_PARALLEL=1
OLLAMA_MAX_LOADED_MODELS=1
# Pozostaw puste, chyba że obsługujesz klientów przeglądarkowych, którzy łączą się bezpośrednio z Ollama.
OLLAMA_ORIGINS=
Mała, ale ważna niuans: sam Ollama ma domyślne powiązanie hosta 127.0.0.1:11434 w ogólnych konfiguracjach, ale oficjalny obraz kontenera ustawia OLLAMA_HOST=0.0.0.0:11434, aby usługa była osiągalna przez opublikowane porty.
Jeśli chcesz szybkiej weryfikacji bez angażowania jakichkolwiek SDK klienta, API Ollama zawiera endpoint “list local models” pod adresem GET /api/tags.
Trwałe przechowywanie modeli i najmniej bolesny sposób ich przenoszenia
Jeśli zapamiętasz tylko jedną rzecz, niech to będzie ta: kontener musi mieć trwałe przechowywanie, w przeciwnym razie każde ponowne budowanie oznacza ponowne pobieranie.
Ollama pozwala wybrać katalog modeli przy użyciu OLLAMA_MODELS. W referencyjnej implementacji domyślnie jest to $HOME/.ollama/models, a ustawienie OLLAMA_MODELS nadpisuje to.
Wewnątrz oficjalnego obrazu Docker, $HOME naturalnie mapuje się na układ /root używany przez udokumentowane montowanie woluminu (/root/.ollama), co dokładnie tłumaczy, dlaczego oficjalne przykłady docker run montują ten katalog.
Istnieją dwa wzorce przechowywania, które w praktyce dobrze się sprawdzają:
Nazwany wolumin Docker jest najprostszy i przenośny. Można go również przypadkowo odosobnić, więc warto nadać mu celową nazwę (na przykład ollama) i utrzymać go stabilnym podczas refaktoryzacji Compose.
Montowanie powiązane (bind mount) do dedykowanego dysku jest lepsze, gdy rozmiary modeli zaczynają dominować w systemie plików root. W takim przypadku montujesz cały /root/.ollama do tego dysku lub montujesz niestandardowy katalog i wskazywujesz na niego OLLAMA_MODELS.
Jeśli aktywnie reorganizujesz przechowywanie, tutaj pomoże wyraźny scenariusz “przeniesienia modeli”. Zobacz: move-ollama-models .
Obsługa GPU NVIDIA z Compose i NVIDIA Container Toolkit
Ollama może używać GPU NVIDIA w Dockerze, ale obraz nie może magicznie stworzyć GPU. Host musi mieć działające sterowniki NVIDIA i narzędzie NVIDIA Container Toolkit, a Docker musi być skonfigurowany do jego używania. Oficjalna dokumentacja Ollama dla Docker wyraźnie wskazuje na instalację nvidia-container-toolkit, konfigurowanie środowiska uruchomieniowego za pomocą nvidia-ctk runtime configure --runtime=docker i restart Docker.
Po stronie Compose, czystym i nowoczesnym sposobem są rezerwacje urządzeń. Docker dokumentuje dostęp do GPU w Compose przy użyciu deploy.resources.reservations.devices, z capabilities: [gpu], driver: nvidia oraz count (w tym all) lub device_ids.
Dodaj to do usługi ollama, gdy jesteś na hostie NVIDIA:
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
Jeśli masz wiele GPU i chcesz trzymać Ollama na konkretnych urządzeniach, zmień count na device_ids, jak dokumentuje Docker (są one wzajemnie wykluczające).
Czasami zobaczysz starsze przykłady Compose używające runtime: nvidia. To może powodować błędy na nowszych konfiguracjach, takie jak “unknown or invalid runtime name: nvidia”, co jest silną wskazówką, że powinieneś przejść na wsparty wzorzec rezerwacji urządzeń i upewnić się, że toolkit jest skonfigurowany na hostcie.
Użyteczny detal ukryty na widoku: oficjalny obraz ollama/ollama ustawia NVIDIA_VISIBLE_DEVICES=all i NVIDIA_DRIVER_CAPABILITIES=compute,utility. To standardowe sterowniki rozpoznawane przez środowisko uruchomieniowe NVIDIA i są już obecne, chyba że je nadpiszesz.
Aby potwierdzić, czy faktycznie otrzymujesz inferencję na GPU (a nie tylko kontener, który się uruchamia), Ollama zaleca użycie ollama ps i sprawdzenie kolumny “Processor”, która pokazuje, czy model jest w pamięci GPU.
Sprawdzenie rzeczywistości platformy: Ollama zaznacza, że przyspieszenie GPU w Dockerze jest dostępne na Linuxie (i Windows z WSL2), ale nie jest dostępne na Docker Desktop dla macOS z powodu braku przejścia GPU.
Wybory sieciowe: host vs bridge, porty i CORS
Sieć to miejsce, gdzie pojawia się większość błędów “działa, ale moja aplikacja nie może się połączyć”.
Sieć mostkowa z opublikowanymi portami
Domyślna sieć Compose to sieć mostkowa. W tej konfiguracji publikacja 11434:11434 sprawia, że Ollama jest osiągalna z hosta na porcie 11434, podczas gdy inne kontenery powinny komunikować się z nią przy użyciu nazwy usługi ollama (nie localhost). Wielu ludzi wpada na to, ponieważ localhost wewnątrz kontenera oznacza “ten kontener”, a nie “kontener Ollama”.
Sam Ollama uruchamia serwer HTTP na porcie 11434 (obraz go wystawia), a powszechną konwencją jest, że klienci używają http://localhost:11434 na hostcie, gdy porty są opublikowane.
Sieć hosta
network_mode: host może być kusząca na serwerze jednowęzłowym, ponieważ usuwa publikację portów i upraszcza semantykę localhost. Kompromisem jest utrata izolacji i korzyści z nazewnictwa sieci mostkowej, a większe ryzyko kolizji portów.
Celowe wystawienie Ollama
Ollama w normalnej instalacji domyślnie powiązuje się z 127.0.0.1, a udokumentowanym sposobem zmiany adresu powiązania jest OLLAMA_HOST.
W Dockerze masz dwie warstwy:
Adres powiązania Ollama, sterowany przez OLLAMA_HOST (obraz kontenera domyślnie powiązuje się ze wszystkimi interfejsami wewnątrz kontenera).
Osiągalność z zewnątrz kontenera, sterowana przez ports Compose i zapórę ogniową hosta.
Wzorem, który lubię, jest “powiązanie lokalnie domyślnie” przez 127.0.0.1:11434:11434, a następnie zmiana na 0.0.0.0:11434:11434 tylko wtedy, gdy mam powód, by to wystawić.
Klienci przeglądarkowe i OLLAMA_ORIGINS
Jeśli interfejs przeglądarkowy lub rozszerzenie wywołuje Ollama bezpośrednio, jesteś w strefie CORS. Ollama domyślnie pozwala na żądania między domenami z 127.0.0.1 i 0.0.0.0, a dodatkowe źródła można skonfigurować za pomocą OLLAMA_ORIGINS.
To ma znaczenie nawet na jednym węźle, ponieważ “działa z curl” nie oznacza “działa z aplikacji przeglądarkowej”.
Wzorce aktualizacji i cofania, które pasują do serwera jednowęzłowego
Ollama ewoluuje szybko. Twój plik Compose może sprawić, że to będzie spokojny proces, a nie zaskoczenie w środku nocy.
Aktualizacja przez zmianę tagu, a nie liczenie na “latest”
Najbardziej praktyczną strategią aktualizacji jest zablokowanie obrazu na znany dobry tag w .env i celowe jego podnoszenie. Obraz jest publikowany jako ollama/ollama na Docker Hub.
Ponieważ dane modeli i stan serwera są przechowywane w zamontowanym katalogu (/root/.ollama w oficjalnej dokumentacji), zastąpienie kontenera nie implikuje ponownego pobierania modeli.
Cofnięcie to po prostu powrót do poprzedniego tagu
Cofnięcie to ten sam mechanizm w odwrotnej kolejności: ustaw poprzedni tag, odtwórz kontener, zachowaj ten sam wolumin. To tutaj zablokowanie zwraca się zyskiem.
Migracja danych to głównie ścieżki przechowywania
Większość “migracji” w konfiguracji jednowęzłowej nie dotyczy schematów baz danych. Dotyczą układu dysku. Jeśli zmienisz katalog modeli (przez OLLAMA_MODELS) lub przeniesisz zamontowany wolumin na nowy dysk, wykonujesz migrację danych, niezależnie od tego, czy tak ją nazwiesz.
Jeśli chcesz praktycznego przewodnika po reorganizacji katalogu modeli na prawdziwych maszynach, zobacz: move-ollama-models .
Ostateczna uwaga, którą łatwo przeoczyć: dokumentacja API Ollama wyraźnie mówi, że API ma być stabilne i wstecznie kompatybilne, z rzadkimi deprecjacjami ogłaszanymi w notach wydania. To sprawia, że “zaktualizuj serwer, zachowaj działanie klientów” jest rozsądnym domyślnym oczekiwaniem dla punktu końcowego usługi jednowęzłowej.
Częste awarie: uprawnienia GPU, niepasujące sterowniki i OOM
Ta sekcja jest celowo dążona do objawów. Celem nie jest “każdy możliwy błąd Docker”, tylko awarie, które pojawiają się specyficznie w konfiguracjach Ollama + GPU + trwałe przechowywanie.
GPU widoczne na hostcie, brakujące w kontenerze
Jeśli host ma działający sterownik NVIDIA, ale kontener nie widzi GPU, częste przyczyny to:
NVIDIA Container Toolkit nie jest zainstalowany lub środowisko uruchomieniowe Docker nie jest skonfigurowane przez nvidia-ctk. Dokumentacja Ollama dla Docker wskazuje na to bezpośrednio.
Compose nie rezerwuje urządzenia GPU. Współczesny sposób to deploy.resources.reservations.devices z możliwością gpu, jak dokumentuje Docker.
Stara konfiguracja runtime: nvidia jest używana na daemonie, który jej nie rozpoznaje, co powoduje “unknown or invalid runtime name: nvidia”.
Do walidacji, ollama ps daje praktyczną kontrolę: pokazuje, czy model jest załadowany w pamięci GPU.
Brak uprawnień do urządzeń GPU
Typ “permission denied” w awariach GPU zazwyczaj wskazuje na ograniczenia środowiskowe, a nie sam Ollama. Przykłady obejmują uruchamianie Docker bez roota, polityki bezpieczeństwa lub węzły urządzeń niebywych tak, jak oczekiwano. Dokumentacja Docker Compose dla GPU jest wyraźna, że host musi mieć urządzenia GPU i że daemon Docker musi być odpowiednio ustawiony.
W razie wątpliwości, zmniejsz zmienne: potwierdź konfigurację toolkita (host), następnie potwierdź rezerwację GPU (Compose), a następnie potwierdź użycie GPU (ollama ps).
Zły sterownik, złe oczekiwania
Ollama w Dockerze polega na stosie sterowników hosta. Jeśli sterownik hosta jest brakuje, jest za stary lub źle skonfigurowany, zobaczysz błędy, które wyglądają jak “Ollama jest zepsuta”, ale w rzeczywistości to “stos CUDA nie jest używalny”. Oficjalna dokumentacja stawia narzędzie kontenera i konfigurację daemon Docker jako wymagania wstępne dla używania GPU NVIDIA.
Brak pamięci: VRAM lub RAM znika szybko
OOM (Out of Memory) jest najbardziej przewidywalnym trybem awarii dla inferencji lokalnej i zazwyczaj jest samowypowiadany przez konfigurację.
Ollama obsługuje przetwarzanie równoległe poprzez wiele załadowanych modeli i obsługa żądań równolegle, ale jest ograniczona dostępną pamięcią (systemowa RAM dla inferencji na CPU, VRAM dla inferencji na GPU). Gdy używana jest inferencja GPU, nowe modele muszą zmieścić się w VRAM, aby umożliwić równoległe ładowanie modeli.
Dwie szczegóły konfiguracji warto traktować jako pierwszorzędne “ustawienia serwera”:
OLLAMA_NUM_PARALLEL zwiększa równoległą obsługę żądań dla modelu, ale wymagana pamięć skaluje się z OLLAMA_NUM_PARALLEL * OLLAMA_CONTEXT_LENGTH.
OLLAMA_KEEP_ALIVE kontroluje, jak długo modele pozostają załadowane (domyślnie 5 minut). Trzymanie modeli załadowanych zmniejsza opóźnienia zimnego startu, ale też blokuje pamięć.
Jeśli stabilizujesz usługę jednowęzłową pod obciążeniem, nie-dramatyczne naprawy zazwyczaj wyglądają tak:
Zmniejsz równoległość i domyślne konteksty zanim cokolwiek innego zmienisz.
Ogranicz, ile modeli może pozostawać załadowanych jednocześnie.
Rozważ funkcje redukcji pamięci, takie jak Flash Attention (OLLAMA_FLASH_ATTENTION=1) i typy pamięci podręcznej K/V o niższej precyzji (OLLAMA_KV_CACHE_TYPE), gdy wąskim gardłem jest pamięć, a nie surowa moc obliczeniowa.
Gdy to nie jest Ollama: wybór Docker Model Runner
Czasami “awaria” to w rzeczywistości niedopasowanie narzędzi. Jeśli Twoja organizacja już standaryzowała się na artefaktach i przepływach pracy natywnych dla Docker, Docker Model Runner (DMR) może być lepszym wyborem niż uruchamianie Ollama jako długotrwały kontener usługi.
Docker pozycjonuje DMR jako sposób na zarządzanie, uruchamianie i serwowanie modeli bezpośrednio przez Docker, pobierając z Docker Hub lub innych rejestrów OCI, oraz serwowanie API kompatybilne z OpenAI i Ollama.
Obsługuje również wiele silników inferencji (w tym llama.cpp i vLLM na Linuxie z GPU NVIDIA), co może mieć znaczenie, jeśli zależy Ci na charakterystyce przepustowości, a nie tylko na “uruchomieniu jednego modelu lokalnie”.
Jeśli chcesz praktycznego odniesienia poleceń i głębszego kąta porównawczego, zobacz: Docker Model Runner Cheatsheet: Komendy i Przykłady.