Ollama в Docker Compose с поддержкой GPU и постоянным хранением моделей

Сервер Ollama с приоритетом композиции, поддержкой GPU и сохранением данных.

Содержимое страницы

Ollama отлично работает на «голом железе». Всё становится ещё интереснее, когда вы начинаете относиться к нему как к сервису: стабильный эндпоинт, закреплённые версии, постоянное хранилище данных и GPU, который либо доступен, либо нет.

В этой статье речь идёт об одной цели: воспроизводимый локальный или одноузловой «сервер» Ollama с использованием Docker Compose, с ускорением на GPU и постоянным хранением моделей.

ollama docker compose

Здесь намеренно пропущены основы Docker и Compose. Когда вам нужен компактный список наиболее часто используемых команд (образы, контейнеры, тома, docker compose), хорошим дополнением служит Шпаргалка по Docker.

Если вы хотите использовать HTTPS перед Ollama, корректную потоковую передачу (streaming) и проксирование WebSocket, а также управление на краевых точках (аутентификация, тайм-ауты, ограничение частоты запросов), ознакомьтесь со статьёй [Ollama за обратным прокси с Caddy или Nginx для HTTPS-стриминга](https://www.glukhov.org/ru/llm-hosting/ollama/ollama-behind-reverse-proxy/ “Безопасно выведите Ollama за Caddy или Nginx с автоматическим HTTPS, опциональной базовой аутентификацией или SSO на входе, а также с корректным стримингом и проксированием WebSocket. Включает настройки тайм-аутов, ловушки буферизации, лимиты частоты запросов и проверки через curl.”}).

Чтобы понять, как Ollama вписывается в окружение с vLLM, Docker Model Runner, LocalAI и облачным хостингом, а также разобраться в компромиссах, см. статью [Хостинг LLM в 2026 году: сравнение локальной, самоуправляемой и облачной инфраструктуры](https://www.glukhov.org/ru/llm-hosting/ “Полное руководство по хостингу LLM в 2026 году. Сравнение Ollama, vLLM, Docker Model Runner, LocalAI и облачных провайдеров. Изучите компромиссы по стоимости, производительности и инфраструктуре.”}).

Как только этот стек Compose начинает обрабатывать реальный параллельный трафик, следующим вопросом часто становится: а действительно ли сам Ollama — правильный движок под ним. Статья [Ollama to vLLM: когда мигрировать ваш локальный сервер LLM](https://www.glukhov.org/ru/llm-hosting/comparisons/ollama-to-vllm-migration/ “Узнайте, когда стоит мигрировать с Ollama на vLLM. Признаки для миграции, этапы планирования, настройка Docker Compose и практический чек-лист.”}) предлагает поэтапный путь миграции, позволяющий держать оба контейнера запущенными параллельно во время валидации.

Когда Compose выигрывает у установки на «голое железо»

Нативная установка бесшовна для одного разработчика на одной машине. Но как только у вас появляется что-то из перечисленного ниже, Compose начинает выигрывать по эргономике:

Настройка для команды выигрывает от того, что определение сервиса представляет собой файл, который можно просматривать, версионировать и разделять. Одноузловой сервер выигрывает потому, что обновления сводятся к смене тега образа и перезапуску, пока хранение моделей остаётся на месте (при условии, что оно находится на томе). Кроме того, Ollama часто находится в соседстве с сайд-карами: веб-интерфейсом, обратным прокси, аутентификационным гейтвеем, векторной БД или рантаймом агентов. Compose хорошо подходит для «одна команда — и весь стек запущен», не превращая ваш хост в уникальную снежинку.

Такой подход хорошо согласуется с тем, как спроектирован официальный контейнер Ollama: образ по умолчанию запускает ollama serve, открывает порт 11434 и предназначен для хранения состояния в монтируемом каталоге. Полный набор переменных окружения OLLAMA_*, которые читает ollama serve — OLLAMA_HOST, OLLAMA_CONTEXT_LENGTH, OLLAMA_KEEP_ALIVE, OLLAMA_NUM_PARALLEL и другие, — документирован в [Шпаргалке по CLI Ollama](https://www.glukhov.org/ru/llm-hosting/ollama/ollama-cheatsheet/ “Шпаргалка по CLI Ollama: команды ollama serve, run и ps, управление моделями, флаги размышлений и переменные окружения сервера.”}).

Скелет Compose, который действительно полезен для Ollama

Начните с двух решений:

Во-первых, как вы будете закреплять версии. Образ на Docker Hub называется ollama/ollama, поэтому вы можете зафиксировать конкретный тег в файле .env, а не полагаться на latest.

Во-вторых, где будут находиться данные моделей. Официальная документация монтирует том в /root/.ollama, чтобы модели не скачивались заново каждый раз, когда контейнер заменяется.

Вот файл Compose, который встраивает эти решения и держит «настроечные ручки» близко к определению сервиса:

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

    # По умолчанию держим локально, при необходимости открываем позже.
    ports:
      - "${OLLAMA_BIND_IP:-127.0.0.1}:11434:11434"

    # Постоянное хранение моделей и состояния сервера.
    volumes:
      - ollama:/root/.ollama

    environment:
      # Официальный образ уже по умолчанию привязывается к 0.0.0.0:11434 внутри контейнера,
      # но явное указание помогает, если вы впоследствии переопределяете настройки.
      - OLLAMA_HOST=0.0.0.0:11434

      # Настройка параметров сервиса.
      - OLLAMA_KEEP_ALIVE=${OLLAMA_KEEP_ALIVE:-5m}
      - OLLAMA_NUM_PARALLEL=${OLLAMA_NUM_PARALLEL:-1}
      - OLLAMA_MAX_LOADED_MODELS=${OLLAMA_MAX_LOADED_MODELS:-1}

      # Необязательно, но актуально, если веб-интерфейс в браузере напрямую обращается к Ollama.
      # См. раздел "Сетевые настройки" о причине существования этой переменной.
      - OLLAMA_ORIGINS=${OLLAMA_ORIGINS:-}

    # Резервирование GPU — отдельный раздел ниже.
    # Добавляйте только на хостах, где действительно есть GPU NVIDIA.

volumes:
  ollama: {}

Сопутствующий файл .env делает обновления предсказуемыми:

# Зафиксируйте версию образа, которую вы протестировали.
OLLAMA_IMAGE_TAG=latest

# По умолчанию локально. Смените на 0.0.0.0, когда вы намеренно хотите открыть доступ.
OLLAMA_BIND_IP=127.0.0.1

# Настройка Keep-alive балансирует задержку холодного старта и потребление памяти.
OLLAMA_KEEP_ALIVE=5m

# Параметры параллелизма.
OLLAMA_NUM_PARALLEL=1
OLLAMA_MAX_LOADED_MODELS=1

# Оставьте пустым, если вы не обслуживаете браузерные клиенты, обращающиеся к Ollama напрямую.
OLLAMA_ORIGINS=

Небольшая, но важная тонкость: сам Ollama по умолчанию привязывается к 127.0.0.1:11434 в общей конфигурации, но официальный контейнер устанавливает OLLAMA_HOST=0.0.0.0:11434, чтобы сервис был доступен через опубликованные порты.

Если вы хотите быстрой проверки без использования клиентских SDK, API Ollama включает эндпоинт «список локальных моделей» по адресу GET /api/tags.

Постоянное хранение моделей и самый безболезненный способ его переноса

Если вы запомните только одно, пусть это будет: контейнер должен иметь постоянное хранилище, иначе каждое пересборка приведет к повторному скачиванию.

Ollama позволяет выбрать каталог моделей с помощью OLLAMA_MODELS. В референсной реализации значение по умолчанию — $HOME/.ollama/models, а установка OLLAMA_MODELS переопределяет его.

Внутри официального Docker-образа $HOME естественно соответствует структуре /root, используемой в задокументированном монтировании тома (/root/.ollama), что и объясняет, почему в официальных примерах docker run монтируется именно этот каталог.

Существуют два шаблона хранения, которые хорошо работают на практике:

Именованный том Docker — самый простой и переносимый вариант. Однако его легко случайно оставить «сиротой», поэтому стоит намеренно присвоить ему имя (например, ollama) и сохранять его стабильным при рефакторинге Compose.

Монтирование привязки (bind mount) на выделенный диск лучше подходит, когда размер моделей начинает доминировать над корневой файловой системой. В этом случае вы либо монтируете весь /root/.ollama на этот диск, либо монтируете пользовательский каталог и указываете OLLAMA_MODELS на него.

Если вы активно реорганизуете хранилище, здесь пригодится явная «инструкция по переносу моделей». См.: move-ollama-models .

Поддержка GPU NVIDIA с Compose и NVIDIA Container Toolkit

Ollama может использовать GPU NVIDIA в Docker, но образ не способен «из воздуха» создать GPU. На хосте необходимы рабочие драйверы NVIDIA и NVIDIA Container Toolkit, а Docker должен быть настроен для их использования. Документация Docker для Ollama явно указывает на необходимость установки nvidia-container-toolkit, настройки рантайма через nvidia-ctk runtime configure --runtime=docker и перезапуска Docker.

С точки зрения Compose, чистый и современный способ — это резервирование устройств. Docker документирует доступ к GPU в Compose через deploy.resources.reservations.devices с capabilities: [gpu], driver: nvidia и либо count (включая all), либо device_ids.

Добавьте это в сервис ollama, если вы находитесь на хосте с NVIDIA:

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

Если у вас несколько GPU и вы хотите держать Ollama на определенных устройствах, перейдите от count к device_ids, как описано в документации Docker (они взаимоисключающи).

Иногда вы можете встретить устаревшие примеры Compose, использующие runtime: nvidia. Это может не сработать в новых сборках с ошибками вроде «unknown or invalid runtime name: nvidia», что является сильным намеком перейти на поддерживаемый шаблон резервирования устройств и убедиться, что тулкит настроен на хосте.

Полезная деталь, которая скрывается на виду: официальный образ ollama/ollama устанавливает NVIDIA_VISIBLE_DEVICES=all и NVIDIA_DRIVER_CAPABILITIES=compute,utility. Это стандартные параметры, распознаваемые рантаймом контейнеров NVIDIA, и они уже присутствуют, если вы их не переопределили.

Чтобы подтвердить, что вы действительно получаете инференс на GPU (а не просто контейнер, который запускается), Ollama рекомендует использовать ollama ps и проверять столбец «Processor», который показывает, находится ли модель в памяти GPU.

Проверка реальности платформы: Ollama отмечает, что ускорение на GPU в Docker доступно в Linux (и Windows с WSL2), но недоступно в Docker Desktop для macOS из-за отсутствия пропускной способности GPU (passthrough).

Сетевые варианты: host vs bridge, порты и CORS

Сеть — это место, где возникает большинство багов вида «запускается, но мое приложение не может подключиться».

Сетевая конфигурация Bridge с опубликованными портами

Сетевая конфигурация Compose по умолчанию — это bridge-сеть. В такой настройке публикация 11434:11434 делает Ollama доступным с хоста на порту 11434, в то время как другие контейнеры должны обращаться к нему, используя имя сервиса ollama (а не localhost). Многие спотыкиваются об это, потому что localhost внутри контейнера означает «этот контейнер», а не «контейнер Ollama».

Сам Ollama запускает HTTP-сервер на порту 11434 (образ его открывает), и общепринятая конвенция состоит в том, что клиенты используют http://localhost:11434 на хосте, когда порты опубликованы.

Сетевая конфигурация Host

network_mode: host может казаться привлекательным на одноузловом сервере, так как она устраняет необходимость в публикации портов и упрощает семантику localhost. Компромисс заключается в том, что вы теряете преимущества изоляции и именования пространства, присущие bridge-сети, и с большей вероятностью столкнетесь с конфликтами портов.

Намеренное открытие доступа к Ollama

При стандартной установке Ollama по умолчанию привязывается к 127.0.0.1, и задокументированный способ изменить адрес привязки — это OLLAMA_HOST.

В Docker у вас есть два уровня:

Адрес привязки Ollama, управляемый OLLAMA_HOST (образ контейнера по умолчанию привязывается ко всем интерфейсам внутри контейнера).

Доступность извне контейнера, управляемая ports в Compose и файрволлом хоста.

Мне нравится следующий шаблон: «по умолчанию привязываем локально» через 127.0.0.1:11434:11434, а затем переключаемся на 0.0.0.0:11434:11434 только тогда, когда у меня есть причина открыть доступ.

Браузерные клиенты и OLLAMA_ORIGINS

Если веб-интерфейс в браузере или расширение напрямую обращаются к Ollama, вы находитесь в зоне CORS. По умолчанию Ollama разрешает запросы из других источников с 127.0.0.1 и 0.0.0.0, а дополнительные источники можно настроить с помощью OLLAMA_ORIGINS.

Это важно даже на одном узле, потому что «работает с curl» не означает «работает из браузерного приложения».

Шаблоны обновления и отката, подходящие для одноузлового сервера

Ollama быстро эволюционирует. Ваш файл Compose может превратить этот процесс в спокойный, а не в сюрприз посреди ночи.

Обновление через смену тега, а не надежду, что «latest» будет вести себя адекватно

Самая практичная стратегия обновления — зафиксировать образ в .env с известным рабочим тегом и намеренно его повышать. Образ публикуется как ollama/ollama на Docker Hub.

Поскольку данные моделей и состояние сервера хранятся в смонтированном каталоге (/root/.ollama в официальных документах), замена контейнера не подразумевает повторного скачивания моделей.

Откат — это просто смена тега назад

Откат использует тот же механизм в обратную сторону: установите предыдущий тег, пересоздайте контейнер, сохранив тот же том. Именно здесь закрепление версии окупается.

Миграция данных в основном связана с путями хранения

Большинство «миграций» в одноузловой настройке не касаются схем баз данных. Они касаются структуры дисков. Если вы меняете каталог моделей (через OLLAMA_MODELS) или переносите смонтированный том на новый диск, вы проводите миграцию данных, называете вы это так или нет.

Если вы хотите практического руководства по реорганизации каталога моделей на реальных машинах, см.: move-ollama-models .

Финальное замечание, которое легко упустить: документация API Ollama явно гласит, что API ожидается стабильным и обратно совместимым, с редкими устареваниями, объявленными в заметках о релизе. Это делает «обновите сервер, клиенты продолжают работать» разумным ожиданием по умолчанию для одноузлового сервисного эндпоинта.

Частые сбои: разрешения GPU, несовместимость драйверов и OOM

Этот раздел намеренно ориентирован на симптомы. Цель не в том, чтобы охватить «все возможные ошибки Docker», а только те сбои, которые характерны именно для конфигураций Ollama + GPU + постоянного хранилища.

GPU виден на хосте, но отсутствует в контейнере

Если на хосте работает драйвер NVIDIA, но контейнер не видит GPU, частые причины:

NVIDIA Container Toolkit не установлен или рантайм Docker не настроен через nvidia-ctk. Документация Docker для Ollama прямо указывает на это.

Compose не резервирует устройство GPU. Поддерживаемый способ — deploy.resources.reservations.devices с функциональностью gpu, как описано в документации Docker.

Используется устаревшая конфигурация runtime: nvidia на демоне, который её не распознает, что приводит к ошибке «unknown or invalid runtime name: nvidia».

Для валидации ollama ps дает прагматичную проверку: он показывает, загружена ли модель в память GPU.

Отказ в доступе к устройствам GPU

Сбой GPU типа «отказ в доступе» обычно указывает на ограничения среды, а не на сам Ollama. Примеры включают запуск rootless Docker, политики безопасности или то, что узлы устройств не представлены, как ожидается. Документация по поддержке GPU в Docker Compose явно утверждает, что на хосте должны быть устройства GPU и что демон Docker должен быть настроен соответствующим образом.

Когда сомневаетесь, сократите переменные: подтвердите конфигурацию тулкита (на хосте), затем подтвердите резервирование GPU (в Compose), затем подтвердите использование GPU (ollama ps).

Неправильный драйвер, неправильные ожидания

Ollama в Docker полагается на стек драйверов хоста. Если драйвер хоста отсутствует, слишком старый или настроен неправильно, вы увидите сбои, которые выглядят как «Ollama сломан», но на самом деле являются «стек CUDA недоступен». Официальные документы рассматривают конфигурацию тулкита контейнеров и демона Docker как предварительные условия для использования GPU NVIDIA.

Недостаточно памяти: VRAM или RAM исчезают быстро

OOM (Out of Memory) — самый предсказуемый режим сбоя для локального инференса, и обычно он самоинфлицирован настройками.

Ollama поддерживает параллельную обработку через несколько загруженных моделей и параллельную обработку запросов, но он ограничен доступной памятью (системная RAM для CPU-инференса, VRAM для GPU-инференса). При использовании GPU-инференса новые модели должны помещаться в VRAM, чтобы позволить параллельную загрузку моделей.

Два параметра настройки стоит считать первоклассными «настройками сервера»:

OLLAMA_NUM_PARALLEL увеличивает параллельную обработку запросов на модель, но требуемая память масштабируется как OLLAMA_NUM_PARALLEL * OLLAMA_CONTEXT_LENGTH.

OLLAMA_KEEP_ALIVE контролирует, как долго модели остаются загруженными (по умолчанию 5 минут). Держание моделей загруженными снижает задержку холодного старта, но также закрепляет память.

Если вы стабилизируете одноузовый сервис под нагрузкой, нерезкие исправления обычно выглядят так:

Снизьте значения по умолчанию для параллелизма и контекста, прежде чем менять что-либо еще.

Ограничьте количество моделей, которые разрешено держать загруженными одновременно.

Рассмотрите функции снижения потребления памяти, такие как Flash Attention (OLLAMA_FLASH_ATTENTION=1) и типы кэша K/V с меньшей точностью (OLLAMA_KV_CACHE_TYPE), если вашим узким местом является память, а не чистая вычислительная мощность.

Когда дело не в Ollama: выбор Docker Model Runner вместо

Иногда «сбой» на самом деле является несовпадением инструментов. Если ваша организация уже стандартизировалась на нативных Docker-артефактах и рабочих процессах, Docker Model Runner (DMR) может быть более подходящим, чем запуск Ollama как долгоживущего сервисного контейнера.

Docker позиционирует DMR как способ управления, запуска и обслуживания моделей напрямую через Docker, с загрузкой из Docker Hub или других OCI-реестров, и обслуживанием API, совместимых с OpenAI и Ollama.

Он также поддерживает несколько движков инференса (включая llama.cpp, и vLLM на Linux с GPU NVIDIA), что может иметь значение, если вас интересуют характеристики пропускной способности, а не просто «запустить одну модель локально».

Если вы хотите практическую справку по командам и более глубокую сравнительную перспективу, см.: Шпаргалка по Docker Model Runner: команды и примеры.

Подписаться

Получайте новые материалы про системы, инфраструктуру и AI engineering.