# 云瞰 群晖 DSM 部署（Container Manager / Docker）
#
# 前提：
#   - 群晖 CPU 必须是 Intel 且有核显（DS920+/DS1522+/DS423+ 等 J4125/N5105/N100 机型）
#   - AMD/ARM 机型（DS223j/DS723+ 等）无 /dev/dri，检测只能用 CPU 模式，不适用此文件
#   - DSM 7.2+ Container Manager
#   - 先把镜像传到群晖：docker load < yunkan-image-openvino.tar.gz
#
# 用法：
#   1. 在群晖 File Station 里创建共享文件夹 docker/yunkan（例如 /volume1/docker/yunkan）
#   2. 把本文件 + 镜像 tar 包放到该目录下
#   3. SSH 进群晖执行：
#        docker load < yunkan-image-openvino.tar.gz
#        docker compose -f compose.yml up -d
#   4. 浏览器打开 http://<群晖IP>:23406/ 进入 Setup 向导
#
# 也支持用 DSM Container Manager 的"项目"功能导入本 compose 文件一键启动。
#
# 持久化（两个目录，可分别放不同盘）：
#   data/        小状态：DB / cookies / 日志 / 升级状态（体积小，建议放系统盘 / SSD 卷）。
#                删 data/database.toml 会重新初始化。（模型不在这里——已 bake 进镜像
#                /var/lib/skyview/models，不暴露给客户。）
#   recordings/  录像（可达 TB 级）：嵌套挂到容器内 /app/data/recordings，recordings_dir
#                配置不变，可单独把它指到容量更大的存储卷 / 远端 NAS。
#
# 防火墙：如果群晖开启了"控制面板 → 安全性 → 防火墙"，需放行以下端口：
#   23406/tcp、23880/tcp、24214/tcp、24215/tcp、23515/udp
#
# 注意：群晖不含 OTA 自动升级（updater sidecar）。DSM Container Manager 限制
# 容器访问 docker socket，updater 没法在群晖上跑——这是 DSM 平台限制，不是漏配。
# 升级方式：网页后台 → 设置 → 系统 → 检查更新（手动），或 SSH 里：
#   docker load < yunkan-image-openvino-new.tar.gz
#   docker compose -p yunkan -f compose.yml up -d --force-recreate yunkan

# docker compose 项目名固定为 yunkan：保持和其它平台模板一致，DSM Container
# Manager 导入时"项目"名称也建议填 yunkan。
name: yunkan

services:
  yunkan:
    # 群晖 Intel 机型用 openvino 变体，iGPU 硬件加速解码 + OpenVINO 推理
    image: registry.cn-hangzhou.aliyuncs.com/yunkan/yunkan-openvino:latest
    container_name: yunkan
    restart: always
    pull_policy: never

    # host 网络最省事：WebRTC ICE / RTSP / HLS 多端口直接暴露，不用逐个映射。
    # 群晖 DSM 自带 80/443/5000/5001 端口，云瞰 Dashboard 用 23406（偏移 15326），不冲突。
    #
    # 如果必须用 bridge 网络（比如群晖防火墙策略要求），把 network_mode: host 注释掉，
    # 然后取消下面 ports 段的注释，并确保群晖防火墙放行这些端口。
    network_mode: host

    # ─── bridge 网络端口映射（仅当不用 host 网络时启用）─────────────────
    # ports:
    #   - "23406:23406/tcp"   # Dashboard HTTP（nginx 反代）
    #   - "23880:23880/tcp"   # RTSP
    #   - "24214:24214/tcp"   # HLS
    #   - "24215:24215/tcp"   # WebRTC WHEP
    #   - "23515:23515/udp"   # WebRTC ICE

    # ─── Intel iGPU 核显直通（群晖必须）──────────────────────────────
    # /dev/dri 节点由 kernel i915 模块创建，容器以 root 跑直接可读写。
    # 注意：N100 (Alder Lake-N) 在 DSM 内核上 i915 支持不完整，OpenVINO GPU plugin
    # 可能初始化失败或推理时回退；启动时建议跑一次 vainfo/clinfo 自检。
    devices:
      - /dev/dri:/dev/dri

    volumes:
      # 状态盘：DB / cookies / 日志 / 升级状态（体积小）。（模型不在这里——已 bake 进镜像。）
      - ./data:/app/data
      # 录像盘：可达 TB 级，可指到容量更大的存储卷 / NAS。嵌套覆盖 /app/data/recordings
      # （recordings_dir 配置不变，snapshots / 导出跟录像走）。改这一行左侧路径即可换盘。
      - ./recordings:/app/data/recordings

      # License 硬件指纹：把群晖宿主机稳定标识 bind mount 进容器。
      # 不挂的话每次重建容器 machine-id 随机变 → 指纹变 → license 占新 slot 死循环。
      #
      # 注意：部分群晖机型 product_uuid 在 DMI SMBIOS 里未填，读出来是空或
      # "Not Settable"。容器内 license 模块需要兼容该情况，回退到仅用 machine-id。
      - /etc/machine-id:/etc/machine-id:ro
      - /sys/class/dmi/id/product_uuid:/sys/class/dmi/id/product_uuid:ro

    environment:
      - TZ=Asia/Shanghai
      - SKYVIEW_SELF_CONTAINER_NAME=yunkan