Files
cuframes-composer/docs/ru/operations.md
T
gx e76360dbc4 docs: руководства пользователя / разработчика / operations (RU+EN)
Полный комплект документации к 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>
2026-06-04 22:02:47 +01:00

15 KiB
Raw Blame History

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 не обновляется

Чек-лист:

  1. Бридж к HA broker (192.168.88.4) работает?

    docker logs cctv-mosquitto 2>&1 | grep -i 'bridge'
    

    Ищи Connecting bridge ha-bridge и подтверждение connect.

  2. Нужный topic в bridge config?

    docker exec cctv-mosquitto grep 'topic.*in 0' /mosquitto/config/mosquitto.conf
    

    Если новый префикс — добавь topic XXX/# in 0 и restart mosquitto.

  3. Subscriber подключился?

    docker logs cfc-grid 2>&1 | grep 'mqtt-overlay/<id>.*connected'
    
  4. Тестовый publish:

    mosquitto_pub -h 192.168.88.4 -t '<твой topic>' -m 'test' -r
    

    В логах composer'а должно появиться [cfc/mqtt-overlay/<id>] 'test'.

6.4 Motion-mode не переключает layout

Чек-лист:

  1. Frigate шлёт events?

    mosquitto_sub -h 192.168.88.23 -u composer -P "$PW" \
      -t 'frigate/events' -C 3
    
  2. Composer получает events?

    docker logs cfc-grid 2>&1 | grep 'frigate.*started\|grow\|shrink'
    
  3. Camera-name матчится? frigate=<имя> в --source должно совпадать с event.after.camera.

  4. Zone-filter не отсекает? Если zones=A:B:C в --source — посмотри в Frigate event current_zones. Если пусто или не пересекается — pulse отбрасывается.

  5. 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'а нужно расширить MqttBrokerCfg per-item

9. См. также

  • user.md — настройка композитора
  • developer.md — внутренности, добавление модулей
  • memory/host-and-project.md — общая инфра R9-88.23
  • memory/project_cfc-grid-deployed.md — deploy 1-го прода
  • memory/project_cfc-grid-cpp-refactor.md — Phase 11b refactor
  • memory/incremental-ffmpeg-rebuild.md — incremental docker recipe