Текст и данные · Инструкция
Docker Compose GPU NVIDIA: как подключить GPU
Docker Compose GPU NVIDIA настраивается не установкой драйвера внутрь каждого проекта «с нуля», а передачей уже.
Короткий ответ
Для доступа к NVIDIA GPU хост должен корректно видеть видеокарту, Docker Engine — уметь передавать GPU в контейнер, а в `compose.yaml` нужно объявить GPU device reservation с обязательным `capabilities: [gpu]`. После запуска проверьте доступ к устройству внутри контейнера, например через `nvidia-smi` в совместимом образе.
Что должно работать на хосте до правки compose.yaml
- Операционная система видит NVIDIA GPU и хостовый драйвер установлен без ошибок.
- Docker Engine установлен и запускает обычные контейнеры.
- Настроен совместимый NVIDIA runtime/toolkit для Docker в соответствии с инструкциями вашей платформы.
- Тестовый GPU-контейнер может увидеть устройство до подключения Compose.
- Версия Docker Compose поддерживает используемый синтаксис GPU reservations.
Совет: Сначала докажите, что GPU работает на уровне `docker run`, а уже потом отлаживайте Compose. Иначе две независимые проблемы смешиваются в одну.
Минимальная конфигурация GPU reservation в Compose
Docker показывает GPU-доступ через reservation устройства в секции ресурсов сервиса. В reservation указывают драйвер, количество устройств или их ID и capabilities. Поле capabilities обязательно: документация Docker прямо предупреждает, что без него deployment возвращает ошибку. Для NVIDIA типичный capability — `gpu`.
Практически конфигурация читается так: сервису разрешено зарезервировать GPU-устройство, если оно доступно платформе. `count: 1` означает одно устройство, а `device_ids` позволяет выбрать конкретные GPU по идентификаторам. Эти параметры не нужно задавать одновременно для одной reservation — выбирают либо количество, либо конкретный список. Если машине доступна одна видеокарта и сервис должен использовать её целиком, `count: 1` обычно понятнее, чем жёстко пришивать ID.
В актуальной Compose specification есть и более короткий ключ `gpus`, эквивалентный device request с неявной capability `gpu`; Docker Docs указывает поддержку этого синтаксиса в Docker Compose 2.30.0 и новее. Если проект должен запускаться на более старых установках Compose или вы хотите явно контролировать `driver`, `count` и `device_ids`, reservation через `deploy.resources.reservations.devices` остаётся документированным вариантом. Для командного проекта зафиксируйте минимальную версию Compose рядом с инфраструктурным кодом, чтобы один и тот же YAML не работал у разработчика и не падал на сервере из-за неподдерживаемого поля.
Предупреждение: Не копируйте `device_ids` с другой машины: идентификаторы устройств зависят от конкретного хоста. Для переносимого Compose-файла чаще удобнее `count`.
Пошагово: дать одному сервису одну GPU
- Убедитесь, что `nvidia-smi` или эквивалентный инструмент работает на хосте и показывает нужную видеокарту.
- Проверьте NVIDIA container runtime/toolkit простым GPU-образом через Docker Engine без Compose.
- В `compose.yaml` откройте нужный сервис и добавьте reservation устройства в `deploy.resources.reservations.devices`.
- Укажите `driver: nvidia`, `count: 1` и обязательное `capabilities: [gpu]` по примеру Docker Docs.
- Запустите проект через `docker compose up` и дождитесь старта сервиса.
- Выполните внутри контейнера команду проверки, доступную в выбранном образе; для CUDA/NVIDIA образов это часто `nvidia-smi`.
- Если GPU не виден, сравните ошибку с результатом одиночного `docker run`: так станет ясно, проблема в runtime или в Compose.
Важно: Используйте образ, который действительно содержит нужные CUDA-библиотеки и диагностические утилиты. Доступ к устройству не добавляет автоматически пользовательские библиотеки в ваш application image.
count или device_ids: как выбрать нужную видеокарту
На рабочей станции с одной GPU выбор прост: запросить одно устройство. На машине с несколькими ускорителями сценарий меняется. Если сервису всё равно, какую карту получить, `count` оставляет выбор платформе и делает файл переносимее. Если модель должна работать на конкретной карте — например, потому что одна GPU занята другим сервисом или карты отличаются по памяти, — используйте `device_ids`.
Перед фиксацией ID посмотрите, какие идентификаторы видит Docker/NVIDIA stack на конкретном хосте. Не ориентируйтесь только на порядок в GUI: после изменений железа или конфигурации предположения о нумерации могут стать неверными. Для нескольких сервисов заранее решите, должны ли они делить одну GPU или использовать разные устройства. Compose reservation описывает доступ, но не заменяет контроль памяти самой модели и приложения.
Не смешивайте `count` и `device_ids` в одной reservation: Docker прямо считает эти параметры взаимоисключающими. Если нужен конкретный ускоритель, укажите его ID; если достаточно любого одного доступного устройства, `count: 1` делает конфигурацию переносимее. На серверах с несколькими GPU после изменений железа или runtime заново проверяйте фактические идентификаторы, а не полагайтесь на старую нумерацию из документации проекта.
Предупреждение: GPU memory — отдельный ограниченный ресурс. Два контейнера могут оба видеть одну карту и конкурировать за VRAM, даже если CPU и RAM каждого контейнера ограничены корректно.
Почему доступ к GPU не равен готовой CUDA-среде
Device reservation решает только одну часть задачи: контейнер получает доступ к GPU как к устройству. Пользовательское пространство внутри образа всё равно должно соответствовать вашему приложению. Если Python-пакет ожидает определённую CUDA-среду, а образ собран без нужных библиотек, GPU будет доступна на уровне runtime, но приложение не заработает. Поэтому для ML и вычислений разумно начинать с официального или заведомо совместимого базового образа, а затем добавлять зависимости проекта.
Не пытайтесь лечить каждую ошибку установкой полного хостового драйвера внутрь контейнера. Архитектура NVIDIA container stack рассчитана на взаимодействие с драйвером хоста. Внутри нужны совместимые runtime-библиотеки и приложение, а не второй независимый kernel driver.
После успешного запуска зафиксируйте проверяемый baseline: версия образа, Compose-конфигурация, модель GPU и минимальный smoke-test. Тогда после обновления драйвера, Docker Engine или image tag можно быстро понять, какой слой изменился.
Для smoke-test разделяйте две проверки: «устройство проброшено» и «приложение реально использует GPU». Сначала выполните минимальную диагностику в образе, где доступен `nvidia-smi` или другой аппаратный тест. Затем уже в рабочем образе проверьте, видит ли ускоритель ваш ML-фреймворк или вычислительная библиотека. Если первый тест проходит, а второй нет, Compose и базовый runtime уже в основном исключены из подозреваемых — ищите несовместимость пользовательских библиотек, CUDA runtime внутри образа или архитектуры пакетов.
Совет: Для production закрепляйте версии образов и зависимостей. Тег `latest` делает повторяемость GPU-окружения хуже, особенно когда CUDA-библиотеки меняются независимо от кода приложения.
Что учитывать
Device reservation решает только одну часть задачи: контейнер получает доступ к GPU как к устройству. Пользовательское пространство внутри образа всё равно должно соответствовать вашему приложению. Если Python-пакет ожидает определённую CUDA-среду, а образ собран без нужных библиотек, GPU будет доступна на уровне runtime, но приложение не заработает. Поэтому для ML и вычислений разумно начинать с официального или заведомо совместимого базового образа, а затем добавлять зависимости проекта. Не…
Источники и проверка
Фактическая часть сверена по первичным источникам (в т.ч. Run Docker Compose services with GPU access). Пример и формулировки — редакция N1RO на 2026-09-22.