# 云瞰 Unraid 6.12+ 部署
#
# 前提:
#   - Unraid 6.12.13+(原生支持 docker compose;旧版需装 Docker Compose Manager plugin)
#   - x86_64 CPU(Intel iGPU 推荐 openvino 变体;NVIDIA GPU 推荐 cuda/trt 变体)
#   - 镜像变体根据硬件选,默认本文件用 openvino;NVIDIA 改 image 为 yunkan-cuda 或 yunkan-trt
#
# 关于 Unraid 习惯的 PUID/PGID(nobody:users = 99:100):
#   本模板用 host network + 容器默认 root 跑,license 硬件指纹和 iGPU 透传都需要
#   root 权限。Unraid 习惯的 nobody:users 模式适用于 bridge 网络 + 非特权容器(常见的
#   媒体类 app),本场景不必,**保持容器内 root 即可**。如有强需求自行加 `user: "99:100"`,
#   但需注意 /etc/machine-id 读权限和 /dev/dri 访问可能受影响。
#
# iGPU 透传(Intel 集显):
#   - 装 "Intel GPU TOP" plugin → 重启 → /dev/dri 出现
#   - 本文件已配 devices: /dev/dri:/dev/dri,自动生效
#
# NVIDIA GPU 透传:
#   - 装 "NVIDIA Driver" plugin → 重启
#   - 把下面 deploy.resources 注释取消,并把 image 换成 yunkan-cuda 或 yunkan-trt
#
# 用法:
#   1. 在 Unraid Web UI → Docker 标签页底部 → "Add Container" 旁边的 "Compose" → "Add New Stack"
#      (或 SSH 进 Unraid:cd /mnt/user/appdata/yunkan && docker compose up -d)
#   2. 粘贴本文件内容,或先 wget 下来再上传
#   3. 浏览器打开 http://<Unraid IP>:23406/ 进入 Setup 向导
#
# 持久化(两个目录,可分别放不同盘):
#   data/        小状态:DB / cookies / 日志 / 升级状态(体积小,建议放 SSD / 缓存池)。
#                (模型不在这里——已 bake 进镜像 /var/lib/skyview/models,不暴露给客户。)
#   recordings/  录像(可达 TB 级):嵌套挂到容器内 /app/data/recordings,recordings_dir
#                配置不变,可单独把它指到阵列大盘 / 专用 ZFS pool / 远端 NAS。
# Unraid 习惯把容器数据放 /mnt/user/appdata/yunkan/ 下,录像建议另指容量更大的存储池。
#
# 防火墙:Unraid 默认无防火墙,所有端口直接暴露在 host 上;如有 host 防火墙需放行:
#   23406/tcp(网页 + App 接口 + 直播,必须)、23515/udp+tcp(实时画面低延迟通道)、
#   23880/tcp(RTSP 直连,可选)。24214/tcp 是内部服务,不需要对外放行。
#
# 外网访问:不用在这里配。网页后台 → 设置 → 通用 → HTTPS 证书,填自己的域名即可
#   自动申请证书(Let's Encrypt DNS-01,不需要开 80 端口),再选一个公网端口(默认
#   23443),路由器上转发这一个 TCP 端口就行;宽带有 IPv6 的话连转发都不用。
#   详见 https://yun-kan.com/docs/remote-access
#
# 升级:网页后台「设置 → 系统升级」一键升级(升级时自动拉起一次性执行容器);
#       也可手动 docker compose pull && up -d。

# ★ 本文件请保存为 compose.yml ★ —— 与其它部署路径统一约定名;升级成功后系统会
# 同步本文件的 image 行,防止手动 force-recreate 时静默降级回旧版本。
#
# docker compose 项目名固定为 yunkan(历史约定,保持稳定);用 Unraid Compose 插件 /
# 图形界面导入本文件时,请把 Stack 名称也填 yunkan。
name: yunkan

services:
  yunkan:
    image: registry.cn-hangzhou.aliyuncs.com/yunkan/yunkan-openvino:latest
    container_name: yunkan
    restart: always

    # Unraid 上 host 网络最省事:WebRTC ICE / RTSP / HLS 多端口直接暴露,不用逐个映射。
    network_mode: host

    # ─── Intel iGPU 直通(需 Intel GPU TOP plugin)──────────────────
    devices:
      - /dev/dri:/dev/dri

    # ─── NVIDIA GPU 直通(需 NVIDIA Driver plugin,并把 image 换成 yunkan-cuda/yunkan-trt)──
    # ★ 启用时同时在 environment 里加一行(NVDEC 硬解必需——默认能力集
    #   不挂载 libnvcuvid,视频解码会静默落回 iGPU/软解白吃 CPU):
    #   - NVIDIA_DRIVER_CAPABILITIES=compute,utility,video
    # deploy:
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           count: all
    #           capabilities: [gpu]

    volumes:
      # 状态盘:DB / cookies / 日志 / 升级状态(体积小)。
      # Unraid 习惯放 /mnt/user/appdata/<app>/。(模型不在这里——已 bake 进镜像。)
      - /mnt/user/appdata/yunkan/data:/app/data
      # 录像盘:可达 TB 级,可指到阵列大盘 / NAS。嵌套覆盖 /app/data/recordings
      # (recordings_dir 配置不变,snapshots / 导出跟录像走)。改这一行左侧路径即可换盘。
      - /mnt/user/appdata/yunkan/recordings:/app/data/recordings

      # License 硬件指纹:把 Unraid 宿主机稳定标识 bind mount 进容器。
      # 不挂的话每次重建容器 machine-id 随机变 → 指纹变 → license 占新 slot 死循环。
      - /etc/machine-id:/etc/machine-id:ro
      - /sys/class/dmi/id/product_uuid:/sys/class/dmi/id/product_uuid:ro

      # OTA 在线升级用(pull + 拉起一次性升级执行容器都走 docker socket)
      - /var/run/docker.sock:/var/run/docker.sock

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