# Контейнеры Docker с GPU и NVIDIA Container Toolkit

> Руководство по GPU в Docker с NVIDIA Container Toolkit: --gpus, выбор устройств, резервирование GPU в Compose, разделяемая память для PyTorch и контейнеры ROCm.

Источник: https://fullgpu.com/ru/docs/docker-containers  
Обновлено: 2026-10-22  
Издатель: FullGPU (https://fullgpu.com/)

Чтобы запускать задачи на GPU в Docker с NVIDIA Container Toolkit, достаточно одного флага, но в реальных конфигурациях нужно чуть больше: выбирать GPU для каждого контейнера, резервировать их в Docker Compose, подбирать базовый образ под версию драйвера и выделять PyTorch достаточно разделяемой памяти. Docker и NVIDIA Container Toolkit уже установлены в наших образах Ubuntu. На серверах AMD вместо этого используются флаги устройств — о них рассказано ближе к концу страницы.

## Проверка Docker и NVIDIA Container Toolkit

```
docker --version
nvidia-ctk --version
docker info | grep -i runtimes
docker run --rm --gpus all ubuntu nvidia-smi
```

Последняя команда должна вывести ту же таблицу GPU, что и на хосте. NVIDIA Container Toolkit монтирует драйвер хоста в контейнер, поэтому драйвер никогда не входит в образы: им нужны только библиотеки CUDA, которые использует ваше приложение. Если вы работаете не под root, запускайте `docker` через `sudo` или добавьте своего пользователя в группу `docker`, которая по сути равнозначна root-доступу.

## Доступ контейнера ко всем GPU или только к некоторым

```
# all GPUs
docker run --rm --gpus all ubuntu nvidia-smi -L
# GPUs 0 and 1 (the inner quotes are required because of the comma)
docker run --rm --gpus '"device=0,1"' ubuntu nvidia-smi -L
# one GPU by UUID, as printed by nvidia-smi -L on the host
docker run --rm --gpus device=GPU-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  ubuntu nvidia-smi -L
```

Внутри контейнера выбранные GPU нумеруются с 0, поэтому GPU 2 и 3 хоста видны как 0 и 1. Надёжнее всего закреплять сервис за конкретным GPU по UUID. Чтобы выполнять восемь независимых задач на 8-GPU-сервере, запускайте по одному контейнеру на каждый GPU с `--gpus device=N`.

Кроме того, NVIDIA Container Toolkit читает переменную `NVIDIA_VISIBLE_DEVICES`, если контейнер запущен со средой выполнения NVIDIA:

```
docker run --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=0,1 \
  ubuntu nvidia-smi -L
```

Если `nvidia` — среда выполнения по умолчанию в `/etc/docker/daemon.json`, то образы, которые задают эту переменную (так делают CUDA-образы NVIDIA), получают все GPU даже без `--gpus`, поэтому, если вам нужно ограничение, задавайте её явно. `CUDA_VISIBLE_DEVICES` работает иначе: эта переменная отбирает GPU внутри контейнера среди уже смонтированных.

## Резервирование GPU в Docker Compose

```
services:
  trainer:
    image: ubuntu:24.04
    command: nvidia-smi -L
    ipc: host
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: ["0", "1"]
              capabilities: [gpu]
```

Запустите сервис командой `docker compose up`: в выводе должны быть два GPU. Чтобы задавать число GPU, а не их идентификаторы, замените `device_ids` на `count: all` или `count: 2`; эти два ключа нельзя использовать вместе, а `capabilities: [gpu]` обязателен. Если команда `docker compose version` завершается с ошибкой, установите плагин Compose: `docker-compose-plugin`, если Docker установлен из репозитория Docker, или `docker-compose-v2`, если из репозитория Ubuntu.

> Опубликованный порт, например `-p 8000:8000`, доступен из интернета, даже если ufw его запрещает, потому что Docker создаёт собственные правила файрвола. Публикуйте сервисы как `-p 127.0.0.1:8000:8000` (в Compose — `"127.0.0.1:8000:8000"`) и ставьте перед ними обратный прокси, как показано в [руководстве по файрволу](https://fullgpu.com/ru/docs/networking-firewall).

## Выбор базового образа CUDA или NGC

- Образы **nvidia/cuda** на Docker Hub бывают трёх видов: `base` (минимальная среда выполнения CUDA), `runtime` (плюс библиотеки CUDA) и `devel` (плюс компилятор и заголовочные файлы), некоторые из них — с cuDNN. Теги строятся по схеме `VERSION-FLAVOR-OS`, например `12.8.1-runtime-ubuntu24.04`.
- **Образы NGC**, например `nvcr.io/nvidia/pytorch`, содержат оптимизированный стек фреймворка и выходят каждый месяц с тегами вида `YY.MM-py3`. В их примечаниях к выпуску указано, какой драйвер нужен каждому тегу.

Выбирайте тег, версия CUDA в котором не выше значения «CUDA Version» в выводе `nvidia-smi` на хосте, а для GPU Blackwell — CUDA 12.8 или новее. Если образу нужен более новый драйвер, чем установлен на хосте, контейнер откажется запускаться с ошибкой `unsatisfied condition: cuda>=`. Это правило объясняется в руководстве [по версиям драйвера и CUDA](https://fullgpu.com/ru/docs/nvidia-drivers-cuda).

## Достаточный объём разделяемой памяти для PyTorch

По умолчанию Docker ограничивает `/dev/shm` объёмом 64 МБ. Рабочие процессы DataLoader в PyTorch и NCCL используют разделяемую память, поэтому обучение завершается с ошибкой «bus error» или сообщением «insufficient shared memory (shm)». Используйте общее с хостом пространство имён IPC или увеличьте лимит (подставьте вместо `YY.MM` актуальный тег):

```
# share the host IPC namespace, as NVIDIA recommends for its PyTorch images
docker run --rm -it --gpus all --ipc=host \
  --ulimit memlock=-1 --ulimit stack=67108864 \
  -v /data:/data nvcr.io/nvidia/pytorch:YY.MM-py3

# or keep IPC isolated with a larger /dev/shm
docker run --rm -it --gpus all --shm-size=16g \
  -v /data:/data nvcr.io/nvidia/pytorch:YY.MM-py3
```

Внутри контейнера команда `df -h /dev/shm` показывает доступный объём. В Compose используйте `ipc: host` или `shm_size: "16gb"`. Для образа vLLM нужно сделать то же самое, как показано в руководстве [по инференсу LLM (большой языковой модели) на vLLM](https://fullgpu.com/ru/docs/pytorch-vllm).

## GPU AMD: аналог для ROCm

```
docker run --rm --device=/dev/kfd --device=/dev/dri \
  --group-add video --ipc=host \
  rocm/pytorch:latest \
  python3 -c "import torch; print(torch.cuda.device_count())"
```

На сервере MI355X эта команда выводит `8`. Стандартный способ запуска контейнеров ROCm — передать файлы устройств вместо `--gpus`: `/dev/kfd` — это вычислительный интерфейс, а в `/dev/dri` находятся файлы устройств GPU. Чтобы ограничить контейнер частью GPU, добавьте `-e HIP_VISIBLE_DEVICES=0,1`. Остальное — в руководстве [по настройке ROCm](https://fullgpu.com/ru/docs/amd-rocm).

## Устранение неполадок

- **could not select device driver "" with capabilities: [[gpu]]** или **unknown or invalid runtime name: nvidia**. Docker не настроен на работу со средой выполнения NVIDIA. Выполните `sudo nvidia-ctk runtime configure --runtime=docker`, затем `sudo systemctl restart docker`.
- **unsatisfied condition: cuda>=X.Y.** Образу нужен более новый драйвер. Используйте более старый тег образа или создайте тикет в личном кабинете по поводу драйвера.
- **Ошибка «permission denied» при подключении к сокету демона Docker.** Используйте `sudo` или добавьте своего пользователя в группу `docker` и войдите заново.

## Связанные страницы

- [Инференс LLM на vLLM](https://fullgpu.com/ru/docs/pytorch-vllm): Инференс LLM с vLLM на вашем GPU-сервере: настройте Python через uv, установите PyTorch и vLLM, проверьте OpenAI-совместимый API и запустите его как службу.
- [Как проверить версию CUDA и драйвера NVIDIA в Ubuntu](https://fullgpu.com/ru/docs/nvidia-drivers-cuda): Проверьте версии драйвера NVIDIA и CUDA в nvidia-smi и nvcc, узнайте, как они должны соотноситься, и добавьте CUDA Toolkit в Ubuntu 24.04 без смены драйвера.
- [Настройка файрвола на GPU-сервере](https://fullgpu.com/ru/docs/networking-firewall): Настройка файрвола на GPU-сервере с ufw: сначала разрешите SSH, фильтруйте IPv6, обойдите ловушку с портами Docker и защитите эндпоинт vLLM с TLS и API-ключом.
- [Образы ОС для GPU-серверов с CUDA, ROCm и Docker](https://fullgpu.com/ru/products/os-images): Образы ОС для GPU-серверов: Ubuntu 22.04 и 24.04 с драйверами NVIDIA, CUDA, Docker и Container Toolkit, а также ROCm для AMD. Узнайте, что предустановлено.
