Клиенту
+79181837373
Наш адрес
г.Краснодар ул. Красная д.61
Телефоны:
Время работы
  • Пн-Сб: с 10:00 до 18:00.
  • Вс: Выходной.
E-mail
Мы в соцсетях
Перейти в контакты
0 0
Каталог
Главная
Закладки
0
Сравнить
0
Контакты

Документация окружения

SEES P2P — Документация окружения
SEES P2P

Документация окружения

Сводка по сервисам, маршрутизации, данным и командам. Актуально для docker-compose проекта.

1) Стек и маршрутизация

Сервисы (docker-compose): caddy, coturn, signaling (Node.js), cams (Flask+Gunicorn), redis, netdata.

  • /user — пользовательская SPA (Caddy → статика).
  • /admin — админская SPA + Basic Auth.
  • /admin/monitor/ — Netdata за Basic Auth (обязателен завершающий слэш).
  • /api/auth/*cams:8000 (регистрация/логин/профиль/выход).
  • /api/cams и /api/camera*cams:8000 (CRUD камер).
  • остальное /api/*signaling:${SIGNAL_PORT}.
  • WebSocketwss://nvr.sees.su{SIGNAL_WS_PATH}.
  • GET /health (Caddy) → 200 OK, GET /healthz (cams) → 200 OK.

2) Дерево каталогов (хост)

/opt/sees-p2p/
├─ docker-compose.yml
├─ .env                                 # переменные окружения
├─ caddy/
│  └─ Caddyfile                         # конфиг фронта (bind-mount)
├─ www/
│  ├─ user/                             # SPA для пользователей (index.html и т.д.)
│  └─ admin/                            # SPA для админки (index.html, status.html)
├─ signaling/
│  └─ index.js                          # Node-сервер сигналинга
├─ cams/
│  ├─ Dockerfile
│  └─ app.py                            # Flask API: auth + камеры + /healthz
└─ coturn/
   └─ turnserver.conf                   # конфиг TURN/STUN

3) Томa Docker

  • caddy_data
    /data в контейнере — сертификаты/ACME
  • caddy_config
    /config в контейнере Caddy
  • redis_data
    /data в контейнере Redis (dump.rdb)
  • netdata_lib / netdata_cache
    данные Netdata

4) Caddy — правила и ключевые блоки

Критично: специфичные маршруты должны идти выше общего @api.

# Глобально
{
  email {ADMIN_EMAIL}
}

{DOMAIN} {
  # --- Cams (до общего /api/*) ---
  @cams path /api/cams*
  handle @cams {
    reverse_proxy cams:8000
  }

  @cam path /api/camera*
  handle @cam {
    reverse_proxy cams:8000
  }

  # --- Auth ---
  @auth path /api/auth*
  handle @auth {
    reverse_proxy cams:8000
  }

  # --- WebSocket сигналинг ---
  @ws path {SIGNAL_WS_PATH}*
  handle @ws {
    reverse_proxy signaling:{SIGNAL_PORT}
  }

  # --- Общее REST сигналинга ---
  @api path /api/*
  handle @api {
    reverse_proxy signaling:{SIGNAL_PORT}
  }

  # --- Админка (SPA) ---
  handle_path /admin* {
    basic_auth {
      admin <bcrypt_hash>
    }
    root * /srv/www/admin
    try_files {path} /index.html
    file_server
  }

  # --- Netdata под Basic Auth ---
  handle_path /admin/monitor* {
    basic_auth {
      admin <bcrypt_hash>
    }
    reverse_proxy netdata:19999 {
      header_up Host {upstream_hostport}
      header_up X-Forwarded-Host {host}
      header_up X-Forwarded-Proto {scheme}
    }
  }

  # --- Пользовательская SPA ---
  handle_path /user* {
    root * /srv/www/user
    try_files {path} /index.html
    file_server
  }

  # --- Health ---
  handle /health {
    respond "OK" 200
  }

  # --- Фоллбек ---
  handle {
    respond "TURN/STUN ready at {DOMAIN}:3478/5349" 200
  }
}
Проверка/перезагрузка
# Проверка конфига локально (с подстановкой env)
docker run --rm \
  -e ADMIN_EMAIL="$(grep -m1 '^ADMIN_EMAIL=' .env | cut -d= -f2)" \
  -e DOMAIN="$(grep -m1 '^DOMAIN=' .env | cut -d= -f2)" \
  -e SIGNAL_PORT="$(grep -m1 '^SIGNAL_PORT=' .env | cut -d= -f2)" \
  -e SIGNAL_WS_PATH="$(grep -m1 '^SIGNAL_WS_PATH=' .env | cut -d= -f2)" \
  -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile:ro \
  caddy:2 caddy validate --config /etc/caddy/Caddyfile

# Перечитать конфиг внутри контейнера
docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile || docker compose restart caddy

5) cams / Flask API

Auth: POST /api/auth/register, POST /api/auth/login, POST /api/auth/logout, GET /api/auth/me

Камеры: GET /api/cams (только свои), POST /api/camera/add, GET/PUT/DELETE /api/camera/<id>

Служебное: GET /healthz

6) Сессии/куки

  • На логине создаётся sid (случайный токен), кладётся в Redis с TTL 7 дней.
  • Клиент получает Set-Cookie: sid=...; Secure; HttpOnly; SameSite=Lax; Path=/.
  • Любой пользовательский запрос читает куку sid и подтягивает профиль.

7) Модель данных Redis

user:{username}            → JSON профиль {username,email,phone,password(hash),created_at}
users:index                → SET всех логинов
sess:{sid}                 → строка c username (TTL 7 дней)
user:{username}:cams       → SET id камер пользователя
camera:{id}                → JSON {id,name,url,owner,created_at}

Файл базы: /data/dump.rdb внутри контейнера Redis (том redis_data).

8) Переменные .env

DOMAIN=nvr.sees.su
ADMIN_EMAIL=...
REDIS_PASSWORD=...
SIGNAL_PORT=...
SIGNAL_WS_PATH=/ws
# coturn
EXTERNAL_IP=...
TURN_SHARED_SECRET=...
RELAY_MIN_PORT=...
RELAY_MAX_PORT=...
REALM=${DOMAIN}

9) Порты и сети

  • Caddy: 80, 443/tcp + 443/udp (HTTP/3)
  • coturn: 3478 (UDP/TCP), 5349 (TLS) + диапазон relay (host network)
  • signaling: ${SIGNAL_PORT} (наружу через Caddy)
  • cams: 8000 (внутренняя сеть, наружу через Caddy)
  • netdata: 19999 (доступ через /admin/monitor/)

10) Проверки (curl)

# user/admin SPA
docker compose exec caddy sh -lc 'curl -I http://localhost/user | head -n1'
curl -I https://nvr.sees.su/user | head -n1
curl -I -u admin:*** https://nvr.sees.su/admin/ | head -n1

# netdata (нужен завершающий слэш)
curl -I -u admin:*** https://nvr.sees.su/admin/monitor/ | head -n1

# cams JSON
curl -si https://nvr.sees.su/api/cams | head -n5

# Регистрация/логин/профиль + камеры
curl -si -X POST https://nvr.sees.su/api/auth/register \
  -H 'Content-Type: application/json' \
  -d '{"username":"demo","password":"demo123","email":"demo@example.com","phone":"+79990000000"}'

curl -c /tmp/sid.txt -b /tmp/sid.txt -si -X POST https://nvr.sees.su/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"demo","password":"demo123"}'

curl -c /tmp/sid.txt -b /tmp/sid.txt -s https://nvr.sees.su/api/auth/me

curl -c /tmp/sid.txt -b /tmp/sid.txt -sX POST https://nvr.sees.su/api/camera/add \
  -H 'Content-Type: application/json' \
  -d '{"name":"Demo Cam","url":"rtsp://example.com/stream"}'

curl -c /tmp/sid.txt -b /tmp/sid.txt -s https://nvr.sees.su/api/cams

11) Бэкап / восстановление Redis

# Снапшот и копия
docker compose exec redis redis-cli -a "$REDIS_PASSWORD" BGSAVE
sleep 2
docker compose cp redis:/data/dump.rdb ./backup/redis/dump-$(date +%F-%H%M%S).rdb

# Восстановление
docker compose stop redis
docker compose cp ./backup/redis/dump-YYYY-MM-DD-HHMMSS.rdb redis:/data/dump.rdb
docker compose start redis

12) Basic Auth (админ)

# Сгенерировать bcrypt-хеш
docker run --rm caddy:2 caddy hash-password --plaintext 'НОВЫЙ_ПАРОЛЬ'
# Вставить хеш в Caddyfile → перезапустить caddy

13) Обновление фронтов

  • Файлы лежат в ./www/user и ./www/admin.
  • Сервить отдаёт Caddy прямо из bind-монта — пересборка не нужна.
  • Если браузер держит старое, сделайте Ctrl+F5 или откройте в инкогнито.

14) Типовые проблемы

  • 502 на /api/auth/* или /api/camera* — проверьте порядок в Caddy: @auth должен быть выше @api.
  • 401/404 на /admin — проверьте Basic Auth и try_files {path} /index.html.
  • 400 на /admin/monitor — используйте со слэшем: /admin/monitor/ и Basic Auth.
  • cams не стартует — смотрите трейс: docker compose logs cams | tail -n 200.
  • user «белый» — как правило кэш. Сверьте исходник curl -s /user | head, сделайте хард-рефреш.

15) Что можно улучшить

  • Подтверждение email/телефона, rate-limit, сброс пароля.
  • Выход со всех устройств, ротация sid.
  • Роли (RBAC) и разграничение API.
  • Секьюрные заголовки (CSP/HSTS) для статики.
  • Скрипт бэкапов scripts/backup.sh (по расписанию).
  • Интеграция /user с auth (UI: вход/выход, только свои камеры).
Документ сгенерирован для текущего состояния проекта. Обновляйте по мере изменений конфигов/сервисов.