Сборка ffmpeg с аппаратным ускорением NVIDIA в Docker кажется простой задачей, пока не столкнёшься с коварными ошибками вроде CUDA_ERROR_NO_DEVICE. Я сам потратил не один час, пытаясь понять, почему nvidia-smi показывает карты, а ffmpeg их «не видит». Давайте разберёмся, как правильно настроить окружение, чтобы избежать подводных камней.
Основная проблема обычно кроется в неполной конфигурации переменных окружения и недостаточных правах доступа к функциям GPU. Даже при корректно установленных драйверах контейнеру могут быть недоступны специфические возможности, необходимые для работы с видео кодеков через CUDA.
Полная настройка Dockerfile
Начнём с базового образа. В вашем случае, возможно, используется nvidia/cuda:12.2.0-devel-ubuntu22.04 – это хороший выбор, но есть нюанс:
Образы с суффиксом -devel содержат полный набор инструментов для компиляции, что увеличивает размер финального образа. Для продакшена можно позже создать многоэтапную сборку.
В разделе установки зависимостей обратите внимание на дублирование некоторых пакетов (libtool, unzip, wget). Это не критично, но лучше привести список в порядок:
RUN apt-get update -qq && apt-get -y install
build-essential
cmake
git
libass-dev
libfreetype6-dev
libharfbuzz-dev
... # остальные пакеты без повторений
Ключевой момент
– установка nv-codec-headers. Эти заголовки необходимы для взаимодействия с аппаратными декодерами NVIDIA, и их отсутствие – частая причина ошибок декодирования:
RUN git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git &&
cd nv-codec-headers &&
make install
Сборка FFmpeg: тонкости конфигурации
В вашем configure-скрипте есть все необходимые флаги, но стоит проверить пути к CUDA:
./configure
--enable-nonfree
--enable-cuda-nvcc
--enable-libnpp
--extra-cflags=-I/usr/local/cuda/include
--extra-ldflags=-L/usr/local/cuda/lib64
... # остальные параметры
После сборки обязательно выполните hash -r – это сбросит кэш путей к исполняемым файлам, что особенно важно при работе с пользовательскими сборками.
Решение ошибки CUDA_ERROR_NO_DEVICE
Даже при правильной настройке Dockerfile можно столкнуться с сообщением «no CUDA-capable device is detected». Вот что действительно важно добавить:
ENV NVIDIA_VISIBLE_DEVICES=all
ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility,video
Почему это работает:
1. NVIDIA_VISIBLE_DEVICES – определяет, какие GPU устройства доступны в контейнере
2. NVIDIA_DRIVER_CAPABILITIES – активирует:
– compute (вычисления CUDA)
– utility (утилиты управления)
– video (аппаратное ускорение видео)
Без этих переменных контейнер получает доступ только к базовым функциям, что и вызывает ошибку при обращении к видеодекодерам.
Проверка работоспособности
После сборки образа выполните:
docker run --gpus all -it ваш-образ ffmpeg -hwaccels
В выводе должны присутствовать:
Hardware acceleration methods:
cuda
vulkan
…
Для теста кодирования попробуйте:
ffmpeg -hwaccel cuda -i input.mp4 -c:v h264_nvenc output.mp4
Возможные проблемы:
- Несовместимость версий CUDA и драйверов – проверьте матрицу совместимости NVIDIA
- Отсутствие библиотек в LD_LIBRARY_PATH – добавьте /usr/local/cuda/lib64
- Ошибки прав доступа – запускайте контейнер с флагом –privileged
Совет: Для продакшена используйте официальные образы ffmpeg с CUDA от jrottenberg – они уже содержат оптимальные настройки.
Теперь вы сможете не только исправить текущую ошибку, но и понимать логику работы CUDA в Docker-окружении. Помните, что настройка GPU-ускорения – всегда баланс между совместимостью версий, правами доступа и правильной конфигурацией переменных среды.