docker: dev environment с CUDA 12.4 + build tools

Dockerfile.dev + docker-compose.dev.yml + docker/README.md.

Base: nvidia/cuda:12.4.1-cudnn-devel-ubuntu24.04.

В контейнер включены:
- CUDA toolkit (nvcc, headers, libs)
- GCC 12, Clang + clang-format + clang-tidy
- CMake + Ninja
- FFmpeg dev headers (6.x системные) — для linking при разработке filter
- Python 3.12 + dev (для Phase 3 bindings)
- Profiling/debug tools: valgrind, gdb, strace, ltrace

docker-compose.dev.yml настройки:
- runtime: nvidia + --gpus all
- ipc: shareable — для cross-container CUDA IPC (Phase 1+)
- shm_size: 2gb — стандартный 64 MB не хватит для frame buffers
- SYS_PTRACE + seccomp:unconfined — для gdb/strace внутри (dev-only)
- bind-mount корня репо → /workspace
- /run/cuframes для Unix sockets

Использование документировано в docker/README.md.

Production-images (FFmpeg-with-plugin, Frigate drop-in) — отдельная
работа в Phase 4.
This commit is contained in:
2026-05-14 21:18:32 +01:00
parent c8ab4522f2
commit 6962bc3c7e
3 changed files with 202 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
# Dev-окружение для cuframes — содержит CUDA toolkit (с nvcc), build tools,
# линкеры/анализаторы. GPU прокидывается через `--gpus all` на runtime.
#
# Base: nvidia/cuda devel-image c CUDA 12.4 + cuDNN 9 на Ubuntu 24.04.
# devel-вариант (не runtime) — нужен для компиляции CUDA-кода (nvcc, headers).
FROM nvidia/cuda:12.4.1-cudnn-devel-ubuntu24.04
# Не запрашивать tzdata interactive при apt
ENV DEBIAN_FRONTEND=noninteractive
# Build tools
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
clang \
clang-format \
clang-tidy \
cmake \
ninja-build \
pkg-config \
gcc-12 g++-12 \
gdb \
git \
nasm \
yasm \
libtool \
autoconf \
automake \
# Системные libs (для FFmpeg build в Phase 2 и для examples)
libavcodec-dev \
libavformat-dev \
libavutil-dev \
libavfilter-dev \
libswscale-dev \
libssl-dev \
# Python для bindings (Phase 3)
python3 \
python3-dev \
python3-pip \
# Profiling / debug tools
valgrind \
strace \
ltrace \
linux-tools-common \
# Просмотр и работа в контейнере
vim \
curl \
wget \
less \
htop \
sudo \
&& rm -rf /var/lib/apt/lists/*
# Симлинки для удобства (CUDA устанавливает специфичные пути)
ENV CUDA_HOME=/usr/local/cuda
ENV PATH=${CUDA_HOME}/bin:${PATH}
ENV LD_LIBRARY_PATH=${CUDA_HOME}/lib64:${LD_LIBRARY_PATH}
# Поднятие лимита открытых файлов для Unix sockets + eventfd (cuframes producer
# может держать N consumers × M eventfds)
RUN echo '* soft nofile 65536' >> /etc/security/limits.conf && \
echo '* hard nofile 65536' >> /etc/security/limits.conf
# Working directory совпадает с bind-mount из docker-compose
WORKDIR /workspace
# Default shell — bash с history-file под /workspace/.bash_history (persistent)
ENV HISTFILE=/workspace/.bash_history
SHELL ["/bin/bash", "-c"]
CMD ["/bin/bash"]
+80
View File
@@ -0,0 +1,80 @@
# Docker for cuframes
Все сборки и тесты делаются в Docker. Хостовый CUDA toolkit не нужен —
только NVIDIA driver + nvidia-container-toolkit.
## Развёртывание dev-окружения
```bash
# Один раз (поднимет dev-контейнер на фоне)
docker compose -f docker/docker-compose.dev.yml up -d
# Войти в контейнер
docker compose -f docker/docker-compose.dev.yml exec dev bash
```
После `up -d` контейнер `cuframes-dev` живёт пока его не остановят. Repo
смонтирован в `/workspace`.
Проверка что CUDA видна:
```bash
docker compose -f docker/docker-compose.dev.yml exec dev nvidia-smi
docker compose -f docker/docker-compose.dev.yml exec dev nvcc --version
```
## Что внутри
| Компонент | Версия | Зачем |
|---|---|---|
| Ubuntu | 24.04 | base |
| CUDA Toolkit | 12.4.1 | для `nvcc`, headers, runtime libs |
| cuDNN | 9 | для возможных bindings к ONNX |
| GCC | 12 | стандартный для Ubuntu 24.04 |
| Clang + clang-format + clang-tidy | системные | code style + static analysis |
| CMake | системный (≥3.28) | build |
| Ninja | системный | быстрее make |
| FFmpeg dev headers | системные (6.x) | для linking при разработке filter |
| Python 3 + dev | системный (3.12) | bindings (Phase 3) |
| Profiling | valgrind, gdb, strace, ltrace | debug-набор |
## Что снаружи (на хосте)
Требуется:
- NVIDIA driver ≥ 555 (для CUDA 12.4)
- [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)
- Docker Engine с `--gpus` поддержкой
- Каталог `/run/cuframes` (создаётся compose'ом с rw-доступом, либо `sudo mkdir -p /run/cuframes && sudo chown $USER /run/cuframes`)
## Ограничения / нюансы
- **`shm_size: 2gb`** — `/dev/shm` контейнера, нужен для CUDA IPC handles
и producer/consumer shared memory rings. Default 64 MB не хватит.
- **`ipc: shareable`** — позволяет связывать namespace с другими контейнерами
через `ipc: "container:cuframes-dev"`. Нужно для cross-container CUDA IPC.
- **`SYS_PTRACE` cap + `seccomp:unconfined`** — для gdb / strace inside.
Снимать в production-builds.
- Sysctl / ulimits — bind-mount файла `/etc/security/limits.conf` в init не
гарантирует применения (зависит от docker config). Если CUDA-IPC даст
`EMFILE` — поднять host-side `ulimit -n 65536` перед `docker compose up`.
## Полезные команды (внутри контейнера)
```bash
# Build cuframes (когда появится CMakeLists.txt)
cmake -B build -S . -G Ninja
cmake --build build -j
# Run tests
ctest --test-dir build --output-on-failure
# Phase 0 spike измерения
./build/tools/spike/pingpong_producer cam_test &
./build/tools/spike/pingpong_consumer cam_test
```
## Distribution / production images
Это **dev-окружение**. Production-images (для FFmpeg-with-cuframes-plugin,
Frigate drop-in) — отдельные Dockerfiles в `docker/ffmpeg-cuframes/` и
`docker/ffmpeg-cuframes-frigate/`, появятся в Phase 4.
+50
View File
@@ -0,0 +1,50 @@
# Dev-окружение: один контейнер с bind-mount к корню репо, GPU доступ.
#
# Запуск:
# docker compose -f docker/docker-compose.dev.yml up -d
# docker compose -f docker/docker-compose.dev.yml exec dev bash
#
# Все артефакты сборки попадают в /workspace/build (на хосте — ./build),
# в git исключены через .gitignore.
services:
dev:
build:
context: ..
dockerfile: docker/Dockerfile.dev
image: cuframes-dev:latest
container_name: cuframes-dev
hostname: cuframes-dev
init: true # PID 1 = tini, чтобы Ctrl-C корректно
stdin_open: true
tty: true
# GPU + CUDA IPC требует shared IPC namespace для cross-process тестов
# внутри docker (producer и consumer в одном контейнере — ок без host)
ipc: shareable
runtime: nvidia
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu, compute, utility, video]
environment:
NVIDIA_VISIBLE_DEVICES: all
NVIDIA_DRIVER_CAPABILITIES: "compute,utility,video"
# Чтобы CUDA IPC handles работали через /dev/shm
# (в default docker /dev/shm обрезан 64 MB; здесь поднимаем)
shm_size: "2gb"
volumes:
# Bind-mount корня репо → /workspace
- ../:/workspace:cached
# CUDA IPC создаёт Unix-sockets в /run/cuframes, /dev/shm — bind на host
# для cross-container scenarios (через ipc=shareable + host-side mounts)
- /run/cuframes:/run/cuframes:rw
# Useful caps для perf / valgrind / gdb
cap_add:
- SYS_PTRACE
security_opt:
- seccomp:unconfined
working_dir: /workspace
command: tail -f /dev/null # держать контейнер живым, в него exec'аемся