deeily 5415daefd5 dvr_admin: Fernet encrypt stream_key, Docker wine support, cleanup fixes
Security / шифрование:
- stream_key (128-byte KDF-derived key для encrypted H.265+) теперь
  шифруется Fernet как и пароль DVR. Добавлены _enc_stream_key /
  _dec_stream_key, расшифровка в _dvr_row, автомиграция plaintext→Fernet
  при старте для существующих записей
- dvrs_add / dvrs_edit шифруют stream_key на INSERT/UPDATE

Resource cleanup:
- release(buf): kill() теперь вне buf.lock + wait(timeout=2) чтобы
  не оставлять зомби-процессов (wine/ffmpeg) после disconnect
- view_playback: при смене ключа старый buffer также wait(timeout=2)

Docker:
- Dockerfile: установка wine + wine32 (i386) + xvfb для PlayCtrl.dll
- Предварительная инициализация WINEPREFIX=/app/.wine во время build
  (избегаем задержек первого wineboot в runtime)
- entrypoint.sh запускает Xvfb на :1, затем gunicorn
- COPY dvr_admin/wine_playm4/ в образ (директория gitignore'д —
  нужно положить вручную перед docker build, см. DEPLOY.md)
- DEPLOY.md: добавлена секция «Требования для сборки» с пояснением
  про wine_playm4/ и варианты без него

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:47:19 +03:00

4.0 KiB
Raw Blame History

DVR Admin — сборка и деплой Docker-контейнера

⚠️ Требования для сборки

Проект использует wine + PlayCtrl.dll для декодирования encrypted H.265+ потоков Hikvision. Для работы этого функционала:

  1. Папка dvr_admin/wine_playm4/ должна присутствовать в build-контексте при сборке образа. Она содержит проприетарные Hikvision DLL (PlayCtrl.dll, SystemTransform.dll, slf.dll и т.д.) и скомпилированный playm4_pb_server.exe. Папка в gitignore — копируй её вручную с dev-машины на сборочную.
  2. Image size ≈ 1.5GB (wine + wine32 + xvfb + DLLs). Если encrypted потоки не нужны, можно удалить эту секцию из Dockerfile.

Если папка wine_playm4/ отсутствует, сборка упадёт на COPY. Тогда либо добавь её, либо удали 2 строки с wine_playm4 из Dockerfile (playback encrypted H.265+ работать не будет, всё остальное — да).


Первый запуск (локально)

cd /home/deeily/git/ISAPI
docker compose -f dvr_admin_docker/docker-compose.yml up -d --build

Приложение будет доступно на http://localhost:5001
Логин по умолчанию: admin / admin
БД и ключ шифрования создаются автоматически в /home/deeily/docker/dvr_admin/


Обновление (пересборка образа)

cd /home/deeily/git/ISAPI/dvr_admin_docker

# Пересобрать и перезапустить (данные сохраняются)
docker compose up -d --build

Перенос на другой сервер

1. Собрать и экспортировать образ

cd /home/deeily/git/ISAPI
docker build -f dvr_admin_docker/Dockerfile -t dvr_admin:latest .
docker save dvr_admin:latest | gzip > dvr_admin_docker/dvr_admin.tar.gz

2. Скопировать на сервер

scp dvr_admin.tar.gz user@server:/opt/dvr_admin/

Также скопировать docker-compose.yml, заменив build: . на image: dvr_admin:latest:

services:
  dvr_admin:
    image: dvr_admin:latest        # вместо build: .
    container_name: dvr_admin
    restart: unless-stopped
    ports:
      - "5001:8000"
    volumes:
      - /opt/dvr_admin/data:/data  # папка для БД на сервере
    environment:
      - SECRET_KEY=<сгенерировать>
      - DATA_DIR=/data
      - FERNET_KEY=<сгенерировать>

3. Запустить на сервере

docker load < dvr_admin.tar.gz
docker compose up -d

Обновление на удалённом сервере

# На локальной машине — пересобрать и экспортировать
# Запускать из корня проекта — app.py и lib/ берутся из dvr_admin/ автоматически
cd /home/deeily/git/ISAPI
# --no-cache обязателен, иначе Docker использует старый кэш и упакует старый app.py
docker build --no-cache -f dvr_admin_docker/Dockerfile -t dvr_admin:latest .
docker save dvr_admin:latest | gzip > dvr_admin_docker/dvr_admin.tar.gz
scp dvr_admin.tar.gz user@server:/opt/dvr_admin/

# На сервере — загрузить новый образ и перезапустить (данные сохраняются)
docker stop dvr_admin && docker rm dvr_admin
docker load < dvr_admin.tar.gz
docker compose up -d

Генерация ключей

# SECRET_KEY
python3 -c "import secrets; print(secrets.token_hex(32))"

# FERNET_KEY
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Просмотр логов

docker logs dvr_admin -f