Полный комплект документации к Phase 11b:
docs/ru/user.md — для админа инсталляции (motion-mode, PTZ,
templates.json, mqtt_overlays.json, ZMQ verbs)
docs/ru/developer.md — архитектура (Cell / Layout / Decoration),
как добавить новый Cell/Decoration, ABI shim,
algorithms (best-fit + asymmetric hysteresis)
docs/ru/operations.md — build (host + jammy + incremental bake),
deploy, logs/telemetry, troubleshooting
(broken pipe, MQTT-overlay, motion-mode)
docs/en/*.md — английская версия всех трёх
README.md — переписан с overview + ссылками на docs/
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
15 KiB
cfc-grid — operations / deploy / troubleshooting
Аудитория: тот кто билдит, деплоит, мониторит cfc-grid в проде.
Если ты пользователь — см. user.md. Если разработчик — см. developer.md.
1. Production setup (R9-88.23)
1.1 Стек
docker compose -f docker-compose.yml \
-f cuda-grid/docker-compose.override.yml \
-f cuframes-composer/docker-compose.override.yml \
-f onvif/docker-compose.override.yml \
up -d
Файлы — в localhost-infra/hosts/R9-88.23/docker/cctv/.
| Сервис | Image | Назначение |
|---|---|---|
cuframes-ipc-anchor |
gx/cuframes:0.4 |
Shared VMM IPC anchor для cuframes |
cuframes-pub-* (parking/back_yard/front_yard/gate_lpr) |
gx/cuframes:0.4 |
RTSP → cuframes per-camera publishers |
cuda-grid-mediamtx |
bluenviron/mediamtx |
RTSP/HLS/WebRTC gateway |
cctv-mosquitto |
eclipse-mosquitto |
MQTT broker (+bridge к 192.168.88.4) |
cfc-grid |
gx/cuframes-composer:0.11b-step1 |
Композитор (главный сервис) |
cfc-grid-ffmpeg |
ffmpeg-vf-cuda-grid:phase4b-final |
H.264 pipe → RTSP push |
cfc-grid-watchdog |
gx/cuda-grid-watchdog:0.4 |
Restart cfc-grid при stuck inboundBytes |
cctv-onvif |
gx/cctv-onvif:0.6 |
ONVIF discovery + PTZ → ZMQ |
cctv-frigate |
ghcr.io/blakeblackshear/frigate |
Object detection → MQTT events |
1.2 Поток кадров
cuframes-pub-X ──VMM──┐
cuframes-pub-Y ──VMM──┼──→ cfc-grid (composer)
cuframes-pub-Z ──VMM──┘ │
│ H.264 NVENC
↓ named pipe /tmp/cfc-pipe-dir/grid.h264
cfc-grid-ffmpeg (re-mux)
│ RTSP push
↓
cuda-grid-mediamtx
rtsp://*/cfc-grid (TCP/UDP)
http://*:8888/cfc-grid (HLS)
http://*:8889/cfc-grid (WebRTC)
1.3 Сети
- Внутренний docker network:
cctv - Внешние порты на R9-88.23:
554/tcp— RTSP (mediamtx)8888/tcp— HLS (mediamtx)8889/tcp— WebRTC (mediamtx)5599/tcp— ZMQ control plane composer'а8085/tcp— ONVIF SOAP (cctv-onvif)3702/udp— WS-Discovery multicast (cctv-onvif)
2. Build
2.1 Local host build (Ubuntu 24.04, dev машина)
cd /home/claude/projects/cuframes-composer
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)
Артефакты в build/src/libcuframes_composer.so и build/examples/grid_record.
ВАЖНО: host'овый бинарь (Ubuntu 24.04, glibc 2.39, libavformat60)
несовместим с runtime контейнером (Ubuntu 22.04 jammy, glibc 2.35,
libavformat58). См. memory incremental-ffmpeg-rebuild.
2.2 Jammy build (для production image)
Использует кешированный builder-контейнер cuframes-composer-builder:cached
(Ubuntu 22.04 + nvidia/cuda:12.4.1-devel + apt-deps):
cd /home/claude/projects/cuframes-composer
# Если builder ещё не закеширован:
docker image inspect cuframes-composer-builder:cached >/dev/null 2>&1 || {
docker run -d --name cfc-builder-tmp \
nvidia/cuda:12.4.1-devel-ubuntu22.04 sleep 3600
docker exec cfc-builder-tmp bash -c '
apt-get update -qq && apt-get install -y -qq --no-install-recommends \
build-essential cmake git pkg-config \
libpng-dev libfreetype-dev \
libzmq3-dev libjson-c-dev libmosquitto-dev \
libavformat-dev libavcodec-dev libavutil-dev'
docker commit cfc-builder-tmp cuframes-composer-builder:cached
docker rm -f cfc-builder-tmp
}
# Сам build:
docker run --rm --gpus all -v "$PWD":/src -w /src/build-jammy \
cuframes-composer-builder:cached \
bash -c 'cmake -DCMAKE_BUILD_TYPE=Release .. && make -j$(nproc)'
Артефакты в build-jammy/.
2.3 Bake image (incremental — без docker build)
Не используем docker build (4GB CUDA pull при cache miss). Вместо:
docker rmi gx/cuframes-composer:0.11b-step1 -f 2>/dev/null
CID=$(docker create gx/cuframes-composer:0.10)
docker cp build-jammy/examples/grid_record "$CID":/usr/local/bin/grid_record
docker cp build-jammy/src/libcuframes_composer.so.0.1.0 \
"$CID":/usr/lib/x86_64-linux-gnu/libcuframes_composer.so.0
docker cp docker/templates.json "$CID":/opt/templates.json
docker cp docker/mqtt_overlays.json "$CID":/opt/mqtt_overlays.json
docker commit \
--change 'ENTRYPOINT ["/usr/local/bin/grid_record"]' \
--change 'CMD ["--help"]' \
--change 'ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility,video' \
"$CID" gx/cuframes-composer:0.11b-step1
docker rm "$CID"
Использует базу gx/cuframes-composer:0.10 (с уже установленными runtime
deps) + накладывает свежие артефакты. Быстрее и без сетевого трафика.
2.4 Build ONVIF image
cd hosts/R9-88.23/docker/cctv/onvif
docker build -t gx/cctv-onvif:0.6 -f Dockerfile .
Python image, лёгкий. Если меняешь server.py — rebuild image (тег
поднимать) + правишь image в docker-compose.override.yml.
3. Deploy
3.1 Прод (R9-88.23)
cd /home/claude/projects/localhost-infra/hosts/R9-88.23/docker/cctv
docker compose -f docker-compose.yml \
-f cuda-grid/docker-compose.override.yml \
-f cuframes-composer/docker-compose.override.yml \
-f onvif/docker-compose.override.yml \
up -d cfc-grid
Compose автоматически recreate'нет контейнер если image tag поменялся в
docker-compose.override.yml.
3.2 Verify post-deploy
# Logs композитора
docker logs --tail 30 cfc-grid 2>&1 | grep -iE "loaded|template|pool|motion"
# Ожидаем что-то типа:
# [cfc/loader] /opt/templates.json: loaded 9 templates
# [cfc/composer] templates loaded: 9 (path='/opt/templates.json')
# [cfc/composer] pool+ 'cam-parking' (frigate=parking_overview prio=100)
# [cfc/composer] motion_mode=1 ttl=45000ms pool=4
# [cfc/composer] grow → template='tpl_3' active=3
3.3 Rollback
sed -i 's|gx/cuframes-composer:0.11b-step1|gx/cuframes-composer:0.10|' \
hosts/R9-88.23/docker/cctv/cuframes-composer/docker-compose.override.yml
docker compose ... up -d cfc-grid
4. Logs
4.1 Live tail
docker logs -f --tail 50 cfc-grid
docker logs -f --tail 30 cfc-grid-ffmpeg
docker logs -f --tail 30 cuda-grid-mediamtx
docker logs -f --tail 30 cctv-onvif
docker logs -f --tail 30 cctv-frigate
4.2 Telemetry pattern
| Маркер | Что значит |
|---|---|
[grid_record] N кадров, M IDR, X МБ за Y.0с (25.0 fps) |
Composer успешно encode'ит каждые ~50 кадров |
[cfc/composer] grow → template='X' |
Применился новый template (расширение, мгновенно) |
[cfc/composer] shrink → template='X' |
Применился новый template после hysteresis (сжатие) |
[cfc/composer] manual override 'X' до +60000ms |
PTZ через ONVIF |
[cfc/composer] manual override expired, возврат в motion-mode |
Auto-возврат после 60s |
[cfc/mqtt-overlay/<id>] '<text>' |
MQTT-overlay получил/отрендерил новый text |
[cfc/frigate] connected, subscribe 'frigate/events' |
Frigate-subscriber подключился |
[cfc/temp] update: 'XX.X°C' |
(старый код, deprecated — теперь mqtt-overlay) |
4.3 Когда что-то сломалось
| Симптом | Где искать |
|---|---|
src active=0 stale=0 dead=4 |
cuframes-pub-* контейнеры; проверь docker ps и сетевой доступ к камерам |
overlay 0 draw failed |
cfc_overlay_text_rebuild_atlas — обычно невалидный шрифт или текст |
| RTSP стрим не отдаёт | cfc-grid-ffmpeg логи; смотри §6.1 |
| TV/ONVIF не находит | cctv-onvif логи; проверь multicast WS-Discovery в LAN |
5. Monitoring
5.1 MQTT health
cfc-grid публикует health в cuda_grid/health/composer/cfc-grid
каждые ~10 секунд:
{
"uptime_s": 3600,
"frames_encoded": 90000,
"fps_actual": 25.0,
"bitrate_kbps": 6000,
"src_active": 4,
"src_stale": 0,
"src_dead": 0,
"idr_count": 1
}
PW=$(grep '^COMPOSER_MQTT_PASSWORD=' \
/home/claude/projects/localhost-infra/hosts/R9-88.23/docker/cctv/.env | cut -d= -f2)
mosquitto_sub -h 192.168.88.23 -u composer -P "$PW" \
-t 'cuda_grid/health/composer/cfc-grid' -v
5.2 Watchdog
cfc-grid-watchdog — отдельный сервис, мониторит mediamtx
inboundBytes для пути cfc-grid. Если 30 секунд молчания —
docker restart cfc-grid.
Логи watchdog'а:
docker logs --tail 30 cfc-grid-watchdog
При срабатывании — публикует в cuda_grid/health/watchdog/cfc-grid.
6. Troubleshooting
6.1 RTSP не отдаёт / cfc-grid-ffmpeg в "Broken pipe"
Симптом: docker logs cfc-grid-ffmpeg показывает
[out#0/rtsp] Task finished with error code: -32 (Broken pipe).
Причина: --intra-refresh в composer'е (без IDR-burst'ов), mediamtx
рвёт RTSP-publisher если не может отдать новому клиенту start-frame.
Лечение:
- Полный restart pipeline:
docker compose ... restart cfc-grid-ffmpeg cfc-grid cuda-grid-mediamtx - Если повторяется — отключить
--intra-refreshв compose override (стоимость: IDR-bursts в bitrate, но стабильнее для downstream клиентов с frequent disconnect/reconnect)
6.2 ffmpeg не получает кадры от RTSP
Симптом: при ffmpeg -i rtsp://192.168.88.23:554/cfc-grid -frames:v 1 out.jpg
зависает на 30+ секунд.
Причина: Composer пишет H.264 без regular IDR (intra-refresh). Новый RTSP-клиент ждёт keyframe для старта декодинга. ffmpeg в default конфигурации не ждёт достаточно долго.
Workaround:
ffmpeg -rtsp_transport tcp \
-analyzeduration 10000000 -probesize 10000000 \
-i rtsp://192.168.88.23:554/cfc-grid \
-frames:v 1 -y out.jpg
Или используй HLS:
ffmpeg -i http://192.168.88.23:8888/cfc-grid/index.m3u8 \
-frames:v 1 -y out.jpg
6.3 MQTT-overlay не обновляется
Чек-лист:
-
Бридж к HA broker (192.168.88.4) работает?
docker logs cctv-mosquitto 2>&1 | grep -i 'bridge'Ищи
Connecting bridge ha-bridgeи подтверждение connect. -
Нужный topic в bridge config?
docker exec cctv-mosquitto grep 'topic.*in 0' /mosquitto/config/mosquitto.confЕсли новый префикс — добавь
topic XXX/# in 0и restart mosquitto. -
Subscriber подключился?
docker logs cfc-grid 2>&1 | grep 'mqtt-overlay/<id>.*connected' -
Тестовый publish:
mosquitto_pub -h 192.168.88.4 -t '<твой topic>' -m 'test' -rВ логах composer'а должно появиться
[cfc/mqtt-overlay/<id>] 'test'.
6.4 Motion-mode не переключает layout
Чек-лист:
-
Frigate шлёт events?
mosquitto_sub -h 192.168.88.23 -u composer -P "$PW" \ -t 'frigate/events' -C 3 -
Composer получает events?
docker logs cfc-grid 2>&1 | grep 'frigate.*started\|grow\|shrink' -
Camera-name матчится?
frigate=<имя>в--sourceдолжно совпадать сevent.after.camera. -
Zone-filter не отсекает? Если
zones=A:B:Cв--source— посмотри в Frigate eventcurrent_zones. Если пусто или не пересекается — pulse отбрасывается. -
TTL не истёк? Logs
motion_ttl=45000(45 сек) — если события приходят реже — камера выпадает из active.
6.5 ONVIF PTZ presets пусты в TV
Причина: TV закешировал старый ответ GetPresets (Phase 9 имена).
Лечение: удалить и заново добавить камеру в TV-клиенте.
6.6 Templates загрузились но motion-mode не использует новый
Composer читает global registry cfc::current_templates() на каждом
кадре — изменение через cfc_layout_load_file (ZMQ или CLI) должно
быть подхвачено сразу. Если нет — проверь:
echo '{"cmd":"list_layouts"}' | python3 -c "
import zmq,json,sys
s = zmq.Context().socket(zmq.REQ)
s.connect('tcp://192.168.88.23:5599')
s.send_json({'cmd':'list_layouts'})
print(json.dumps(s.recv_json(), indent=2, ensure_ascii=False))"
Поле source показывает текущий загруженный path. Если built-in (только
tpl_1 + tpl_4) — JSON не подгрузился (syntax error, кривой path).
7. Конфиги в репо
| Что | Где |
|---|---|
| templates.json | cuframes-composer/docker/templates.json |
| mqtt_overlays.json | cuframes-composer/docker/mqtt_overlays.json |
| compose override | localhost-infra/hosts/R9-88.23/docker/cctv/cuframes-composer/docker-compose.override.yml |
| ONVIF config | localhost-infra/.../onvif/onvif.yaml |
| ONVIF server | localhost-infra/.../onvif/server.py |
| Mosquitto config | localhost-infra/.../cctv/mosquitto/config/mosquitto.conf |
| .env (passwords) | localhost-infra/.../cctv/.env (gitignored) |
После изменения compose override — docker compose ... up -d cfc-grid
автоматически recreate'нет.
8. Известные ограничения / TODO
--intra-refresh↔ RTSP-clients: trade-off bitrate vs latency (см. §6.1)- Watchdog только cfc-grid: cfc-grid-ffmpeg в зомби-state не детектится напрямую; помогает только полный restart
- Hot-reload mqtt_overlays.json: нет ZMQ verb'а
- MQTT-overlay per-broker config: всё через один broker; для
внешнего broker'а нужно расширить
MqttBrokerCfgper-item
9. См. также
- user.md — настройка композитора
- developer.md — внутренности, добавление модулей
memory/host-and-project.md— общая инфра R9-88.23memory/project_cfc-grid-deployed.md— deploy 1-го продаmemory/project_cfc-grid-cpp-refactor.md— Phase 11b refactormemory/incremental-ffmpeg-rebuild.md— incremental docker recipe