# Troubleshooting Реальные грабли которые мы прошли при первой production deployment'е cuframes (Frigate + custom C++ processor + custom Python). Документировано чтобы вы их не повторяли. ## Содержание - [Runtime / CUDA IPC](#runtime--cuda-ipc) - [`cudaIpcOpenEventHandle: invalid device context`](#cudaipcopeneventhandle-invalid-device-context) - [Subscriber timeout (`cuframes_subscriber_create: timeout`)](#subscriber-timeout) - [Permission denied на socket](#permission-denied-на-socket) - [Frigate-specific](#frigate-specific) - [`s6-overlay-suexec: fatal: can only run as pid 1`](#s6-overlay-suexec-fatal-can-only-run-as-pid-1) - [`No such filter: 'scale_cuda'`](#no-such-filter-scale_cuda) - [Missing dynamic .so после ffmpeg replace](#missing-dynamic-so-после-ffmpeg-replace) - [Build / FFmpeg patch](#build--ffmpeg-patch) - [`libcuframes not found` при configure](#libcuframes-not-found-при-configure) - [`ffbuild/library.mak: No such file`](#ffbuildlibrarymak-no-such-file) - [`could not find a working compiler` (GMP)](#could-not-find-a-working-compiler-gmp) - [`zlib: download failed` в crosstool-NG](#zlib-download-failed-в-crosstool-ng) - [`stdbit.h: No such file` при `--enable-cuda-llvm`](#stdbith-no-such-file-при---enable-cuda-llvm) - [Docker / IPC](#docker--ipc) - [Cross-container CUDA IPC: ipc + pid namespace share](#cross-container-cuda-ipc-ipc--pid-namespace-share) - [Buildx container driver не видит host images](#buildx-container-driver-не-видит-host-images) - [Networking / RTSP](#networking--rtsp) - [RTSP/RTP UDP не доходит до клиента (docker NAT)](#rtsprtp-udp-не-доходит-до-клиента-docker-nat) - [`Nonmatching transport in server reply`](#nonmatching-transport-in-server-reply) - [Gitea Actions / CI](#gitea-actions--ci) - [`node: executable file not found`](#node-executable-file-not-found) - [`SyntaxError: Unexpected token '{'` (Node 12)](#syntaxerror-unexpected-token--node-12) --- ## Runtime / CUDA IPC ### `cudaIpcOpenEventHandle: invalid device context` **Симптом**: subscriber сразу после `cuframes_subscriber_create` падает с этой ошибкой. **Причина**: CUDA driver проверяет IPC peer через `/proc//...`. Если процесс publisher'а **не виден** в PID namespace consumer'а — context считается невалидным. **Fix**: shared PID namespace. Docker: ```yaml consumer: ipc: "container:" # shared /dev/shm pid: "container:" # ← вот это критично, без него fail ``` Host process: запуск consumer'а на host'е (либо publisher'а на host'е тоже) — same default namespace. **Caveat**: если consumer image использует s6-overlay (Frigate, linuxserver.io images) — `pid: container:` несовместим (см. [соответствующую секцию](#s6-overlay-suexec-fatal-can-only-run-as-pid-1)). ### Subscriber timeout **Симптом**: `cuframes_subscriber_create: timeout` без других ошибок. **Причины** (в порядке вероятности): 1. `/run/cuframes/.sock` не виден consumer'у — забыли volume-mount 2. `/run/cuframes` смонтирован, но publisher ещё не успел создать socket — увеличить `connect_timeout_ms` 3. Publisher запущен, socket есть, но **permission denied** — см. ниже ### Permission denied на socket **Симптом**: socket виден через `ls -la /run/cuframes/`, owner `root`. Consumer process — non-root user → не может `connect()`. **Fix**: - Запустить consumer как root: `user: root` в compose - Либо изменить permissions socket после создания (publisher delegation) — TBD в v0.2 --- ## Frigate-specific ### `s6-overlay-suexec: fatal: can only run as pid 1` **Симптом**: container Frigate'а в restart loop, в logs только эта ошибка. **Причина**: `pid: container:` сделал Frigate not-PID-1 в shared namespace. s6-overlay v3 strictly требует PID 1 для proper signal handling/zombie reaping. **Fix**: убрать `pid: container:` для Frigate. Только `ipc: container:` shared. **Trade-off**: без shared pid некоторые edge cases CUDA IPC ломаются (см. [соответствующую секцию](#cudaipcopeneventhandle-invalid-device-context)). Frigate **на практике** работает потому что подключается до того как CUDA driver проверяет peer (race window race), но если publisher restart'нётся посередине — Frigate'у не удастся пере-подключиться без перезапуска. **Real fix** (planned v0.2): encoded packet sharing — Frigate detect получает кадры через decoded path (work-around), record получает encoded через socket-based protocol который **не** требует cudaIpcOpenEventHandle. ### `No such filter: 'scale_cuda'` **Симптом**: Frigate ffmpeg subprocess падает с этой ошибкой в `AVFilterGraph`. **Причина**: наш patched FFmpeg собран без `--enable-cuda-llvm` (см. [stdbit.h grабля](#stdbith-no-such-file-при---enable-cuda-llvm)). Без cuda-llvm в FFmpeg нет CUDA filters (scale_cuda, overlay_cuda). **Fix**: в Frigate config.yml явно отключи hwaccel cuda: ```yaml ffmpeg: hwaccel_args: [] # CPU scale вместо scale_cuda ``` Cost: 5-10% CPU per FHD25 камера. **Real fix** (v0.2): publisher-side resize в cuframes сам. ### Missing dynamic .so после ffmpeg replace **Симптом**: после `docker cp` patched ffmpeg в Frigate container — `ldd ffmpeg` показывает `libharfbuzz.so.0 => not found`, `libfribidi.so.0 => not found`, … ~20 missing .so. **Причина**: Frigate's bundled ffmpeg **статически слинкован** (NickM-27/FFmpeg-Builds делает full static build). Все 30+ deps встроены в один binary. Frigate runtime image **не имеет** этих .so packages installed (ему не надо — bundled ffmpeg self-contained). Наш custom ffmpeg — **dynamic linked** (apt deps). Нужны .so на target. **Fix**: либо - `apt install` missing libs в Frigate (additive image modification): ```bash apt install libharfbuzz0b libfribidi0 librist4 libsrt1.5-openssl libssh-4 \ libvpx7 libwebpmux3 libwebp7 libdav1d6 libaom3 libmp3lame0 \ libsvtav1enc1 libtheora0 libvorbis0a libvorbisenc2 \ libx264-164 libx265-199 libopus0 ``` - Либо строить наш ffmpeg static (sources from NickM-27 pipeline) — complex (см. [zlib download / GMP compiler граблю](#zlib-download-failed-в-crosstool-ng)) Best practice: создать `Dockerfile.frigate` overlay поверх Frigate image, который добавляет deps и копирует ffmpeg. Запечь в image, не in-place patch. --- ## Build / FFmpeg patch ### `libcuframes not found` при configure **Симптом**: FFmpeg configure (с `--enable-libcuframes`) fails с этой ошибкой из `enabled libcuframes && require libcuframes ...`. config.log показывает `fatal error: cuframes/cuframes.h: No such file or directory`. **Причины**: 1. **CMake install rules отсутствовали** в libcuframes (early commits до 601806a). `cmake --install` создавал пустой prefix. Fix: обновить cuframes до ≥ 601806a. 2. **Wrong HINTS в find_library**: твой проект ищет в `${CUFRAMES_ROOT}/build/...` но install layout кладёт в `${CUFRAMES_ROOT}/lib`. Добавь оба пути в HINTS. 3. **`rm -f libcuframes.so*`** удалил .so но **.a** file называется `libcuframes_static.a` (не `libcuframes.a`) → linker не находит `-lcuframes`. Fix: либо не удаляй .so, либо переименуй .a при install. ### `ffbuild/library.mak: No such file` **Симптом**: configure FFmpeg success, но `make` падает сразу: `Makefile:123: ffbuild/library.mak: No such file or directory`. **Причина**: вы сделали ваш fork FFmpeg через snapshot (не git clone), и **случайно исключили `ffbuild/`** в rsync. Это **source files** FFmpeg, не build artifacts. **Fix**: убедись что `ffbuild/` есть в твоём FFmpeg checkout (`ls ffbuild/library.mak`). Если делаешь snapshot через rsync — не используй `--exclude=ffbuild`. ### `could not find a working compiler` (GMP) **Симптом**: crosstool-NG build падает на `Installing GMP for host` с `configure: error: could not find a working compiler`. config.log показывает `no, long long reliability test 1`. **Причина**: GMP 6.2.1 имеет known issue с GCC 11+ (Ubuntu 22.04 default). Проверка long-long reliability fail'ит false-positive. **Fix**: pin GMP к 6.3.0 в `ct-ng-config`: ``` CT_GMP_V_6_3=y # CT_GMP_V_6_2 is not set CT_GMP_VERSION="6.3.0" ``` И убедись что crosstool-NG version (commit) поддерживает 6.3.0 (≥ master 2024-09). ### `zlib: download failed` в crosstool-NG **Симптом**: crosstool-NG step `Retrieving 'zlib-1.2.12'` fail'ит. **Причина**: zlib.net убрали старые versions с дефолтного location — теперь они только в `/fossils/` subdirectory. Crosstool-NG hardcoded URL не работает. **Fix**: pre-fetch tarball + положить в local cache: ```bash wget https://zlib.net/fossils/zlib-1.2.12.tar.gz -O preload/zlib-1.2.12.tar.gz ``` В Dockerfile перед `ct-ng build`: ```dockerfile COPY preload/*.tar.gz /root/src/ ``` `CT_LOCAL_TARBALLS_DIR=${HOME}/src` — crosstool-NG найдёт в cache и не пойдёт download. ### `stdbit.h: No such file` при `--enable-cuda-llvm` **Симптом**: FFmpeg configure с `--enable-cuda-llvm` fail'ит: `fatal error: stdbit.h: No such file or directory`. ERROR: cuda_llvm requested but not found. **Причина**: `stdbit.h` — C23 standard header. Доступен в glibc ≥ 2.38. - Ubuntu 22.04 = glibc 2.35 — **нет** - Debian 12 = glibc 2.36 — **нет** - Ubuntu 24.04 = glibc 2.39 — есть - Debian 13 (trixie) = glibc 2.38+ — есть **Fix options**: 1. Build на newer base (Ubuntu 24.04+). Но runtime target (Frigate Debian 12) не запустит binary с glibc-2.38 symbols (backwards-incompatible). 2. Убрать `--enable-cuda-llvm`. Потеря: CUDA filters (`scale_cuda`, `overlay_cuda`, `hwupload_cuda`). Decode/encode через NVDEC/NVENC всё равно работают. 3. Дождаться когда Frigate base обновится до newer Debian — вне твоего контроля. **На практике**: убираем cuda-llvm, в Frigate config `hwaccel_args: []`. См. [scale_cuda секцию](#no-such-filter-scale_cuda). --- ## Docker / IPC ### Cross-container CUDA IPC: ipc + pid namespace share | Что нужно | Compose option | |---|---| | /dev/shm shared (для cuframes header + SHM ring) | `ipc: container:` (либо `ipc: shareable` у publisher + same у consumer) | | /proc visibility (для CUDA IPC peer validation) | `pid: container:` | | `/run/cuframes/*.sock` доступен | volume mount: `cuframes_sock:/run/cuframes:ro` | | GPU access | `runtime: nvidia` | | Socket permissions | `user: root` (либо chmod socket в publisher) | **Все 5** должны быть выполнены. Один пропуск — fail при subscriber_create или cudaIpcOpenEventHandle. ### Buildx container driver не видит host images **Симптом**: при использовании custom buildx builder (`docker buildx create --driver docker-container ...`) с `FROM local-image:tag` — error `failed to authorize: 403 Forbidden` (buildkit пытается pull с registry). **Причина**: container driver buildx изолирован, не имеет доступа к host's local docker daemon images. Pull через registry. **Fix**: либо - Не использовать custom builder — `docker buildx use default` (использует host daemon). Минус: теряем `--cache-to/--cache-from type=local`. - Либо push local image в **registry** (local или gitea), и buildx pull'ит оттуда. --- ## Networking / RTSP ### RTSP/RTP UDP не доходит до клиента (docker NAT) **Симптом**: RTSP server в docker контейнере с `ports: "554:8555"`. Клиент (TV, VLC) делает RTSP SETUP successfully (TCP control работает), но video frames не приходят. **Причина**: RTP идёт **UDP**, sourced из docker network namespace. SNAT MASQUERADE для outbound работает, но RTP destination port (которое клиент опубликовал в SETUP) **не маппится обратно** через docker bridge — клиент видит UDP packets от чужого source IP (docker network 172.x), не от 192.168.88.23 как expected. **Fix**: `network_mode: host` для RTSP-server контейнера. Тогда server listens **напрямую** на host interfaces, RTP packets идут без NAT. Trade-offs: - Все ports app'а listen на host network (нет port mapping). Проверь port collisions. - DB env vars (postgres:5432 в docker network DNS) надо менять на host paths (`localhost:5433` если postgres exposed на host port 5433). ### `Nonmatching transport in server reply` **Симптом**: `ffprobe -rtsp_transport tcp -i rtsp://...` falls с этим сообщением. **Причина**: RTSP server возвращает SDP с UDP-only transport. Client ожидает TCP interleaved. **Fix**: использовать UDP transport: `-rtsp_transport udp` (либо default behavior). Если TV не поддерживает UDP — нужен RTSP server который умеет RTP-over-TCP interleaved (cctv-processor v0.1 не умеет). --- ## Gitea Actions / CI ### `node: executable file not found` **Симптом**: первый JS action (например `actions/checkout@v4`) fail'ит: `OCI runtime exec failed: exec: "node": executable file not found in $PATH`. **Причина**: гитея act_runner запускает JS actions через `node`, но твой custom container (например `nvidia/cuda:...`) не имеет node installed. **Fix**: pre-install node в первом `run:` step (до actions/checkout): ```yaml steps: - name: Bootstrap node run: apt-get update && apt-get install -y nodejs git ca-certificates - name: Checkout uses: actions/checkout@v4 ``` Либо использовать container с node pre-installed (`docker.gitea.com/runner-images:ubuntu-22.04`). ### `SyntaxError: Unexpected token '{'` (Node 12) **Симптом**: после `apt install nodejs` в Ubuntu 22.04 — actions/checkout@v4 fail'ит: `SyntaxError: Unexpected token '{' at static {...}`. **Причина**: Ubuntu 22.04 apt'овский `nodejs` = Node **12**. `actions/checkout@v4` скомпилирован для Node 20+ (static class blocks — ES2022). **Fix**: install Node 20 from NodeSource: ```bash curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs ``` В Ubuntu 24.04 apt уже даёт Node 20 — там goes автоматически.