Viseron 3.7.0 Docker Compose 部署指南

Viseron 3.7.0 从零到一 Compose 部署实测:MediaMTX 模拟摄像头推流接入、内置 PostgreSQL 16 初始化、组件化 config.yaml 全链路配置、检测/录像/快照落盘验证、PAT 接口验证与常见问题实录(2026-10-30)。

ViseronViseronDockerDocker ComposeRTSP2026/10/30

Viseron 3.7.0 Docker Compose 部署指南

目标:在一台 Ubuntu Linux 服务器上,用 Docker Compose 从零到一跑起一套完整的 Viseron 3.7.0 监控检测环境——官方镜像内置 PostgreSQL 16 元数据库,配合 MediaMTX RTSP 流媒体服务器,并用 ffmpeg 循环推流一段测试视频充当「模拟摄像头」,端到端验证拉流、运动检测、AI 物体检测、事件录像与快照全链路。本篇实测的测试源为本地推流模拟(Intel 开源样例视频循环推 RTSP),无真实摄像头硬件,读者的真实摄像头只需把模拟源地址替换为自己的 RTSP 地址即可。

一、环境信息

本篇全部命令与回显在下列实测环境中逐条跑出(2026-10-30):

项目值
操作系统Ubuntu 22.04(Linux x86_64)
服务器配置6 核 CPU / 19GB 内存 / 无独立显卡
DockerDocker Engine 28 + Docker Compose v2
Viseronroflcoopter/viseron:3.7.0(镜像 9.45GB,内置 PostgreSQL 16.15 / FFmpeg / go2rtc / nginx)
RTSP 服务器bluenviron/mediamtx:1.21.3-ffmpeg(镜像 286MB)
模拟源视频person-bicycle-car-detection.mp4(Intel intel-iot-devkit/sample-videos 开源样例,H.264 768x432@12fps + AAC,时长 53.9 秒)
Compose 项目名viseron-3.7.0-stack
Docker 网络viseron-3.7.0-net,10.89.61.0/24
宿主端口8151 → Viseron Web UI(8888)、8150 → MediaMTX RTSP(8554)
实测目录/opt/viseron(文档内路径,读者按需自定)

与多数同类 NVR 不同,Viseron 不依赖 MQTT 消息代理——单个主服务拉起即含数据库、流媒体网关与 Web 服务器,Compose 里只需要 Viseron 主服务加「模拟摄像头」相关服务。

💡 技术拓展:ffmpeg 拉流时的 RTSP 传输方式不止一种,stream_format 参数决定信令与载荷怎么走——

传输方式特点适用场景
rtsp(默认)RTP over UDP 载荷,低开销可靠内网,丢包影响小
tcpRTP over RTSP( interleaved),复用 554 通道跨网段/易丢包环境,抗丢帧
udp纯 UDP 组播/单播特定老旧设备

本篇实测源与 Viseron 在同一 Docker 网络内,链路零丢包,采用默认 stream_format: rtsp;真实摄像头跨交换机/跨 VLAN 接入时建议改 tcp。

二、镜像选型说明

两个镜像均为官方/上游发布,版本与选型理由如下:

服务镜像与 tag选型理由
viseronroflcoopter/viseron:3.7.0官方主镜像(multiarch),3.7.0 为 2026-09-17 发布的最新稳定版;单镜像内置 PostgreSQL 16、FFmpeg、go2rtc、nginx 全部运行时,无需任何外部配套服务。官方另有 amd64-cuda(NVIDIA)、aarch64(ARM64/RPi4)、rpi3、jetson-nano 变体,仅在对应硬件上选用;3.7.0 起同一 tag 亦发布至 ghcr.io/roflcoopter/viseron,可按网络环境二选一
mediamtxbluenviron/mediamtx:1.21.3-ffmpegMediaMTX 是 RTSP/RTMP/HLS/WebRTC 全协议流服务器;选 -ffmpeg 变体因为镜像内置 ffmpeg,同一镜像可同时充当「RTSP 服务器」与「模拟摄像头推流器」,省一个镜像
模拟摄像头bluenviron/mediamtx:1.21.3-ffmpeg(复用)覆盖 entrypoint 直接跑 ffmpeg 循环推流,模拟一台持续在线的摄像头;生产环境去掉该服务、换成真实摄像头 RTSP 地址

⚠️ 注意:镜像 tag 一律固定到具体版本号(如 3.7.0、1.21.3),不要用 latest,保证任何时候重建环境结果可复现。

三、前置条件

  1. 一台 Ubuntu 22.04 服务器,已安装 Docker Engine 与 Docker Compose v2(docker compose version 能正常输出版本)。
  2. 端口 8150/8151 未被占用(ss -ltn 检查;8128-8152 是本文约定端口段,若被占用可自行替换为空闲端口)。
  3. 服务器可访问外网拉取镜像(本篇镜像实际拉取均成功;roflcoopter/viseron:3.7.0 约 9.45GB,磁盘预留至少 15GB)。
  4. 无需 MQTT 代理、无需外置数据库——Viseron 镜像自带 PostgreSQL 16 并随主服务启停。

四、部署步骤

4.1 创建目录结构

所有配置与数据统一收敛到一个部署目录(下文以 /opt/viseron 为例),便于持久化与备份:

mkdir -p /opt/viseron/{config,segments,snapshots,thumbnails,event_clips,timelapse,source}
cd /opt/viseron
tree -L 1 .

实测回显:

.
├── config
├── event_clips
├── segments
├── snapshots
├── source
├── thumbnails
└── timelapse

4.2 准备模拟摄像头测试视频

下载 Intel 开源的检测测试样例视频(BSD-3 许可,包含行人、自行车、汽车三类目标,正好覆盖检测模型的主要类别):

cd /opt/viseron/source
curl -L -o person-bicycle-car-detection.mp4 \
  "https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4"
ls -la person-bicycle-car-detection.mp4

实测回显(GitHub 直连缓慢时可加代理参数,见文末常见问题):

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 5889k  100 5889k    0     0  2453k      0  0:00:02  0:00:02 --:--:-- 2453k
-rw-r--r-- 1 root root 6031199 Oct 30 09:44 person-bicycle-car-detection.mp4

用 ffprobe 核对素材参数(mediamtx 镜像自带 ffprobe,宿主机未装 ffmpeg 时可借用):

docker run --rm -v /opt/viseron/source:/s:ro --entrypoint ffprobe \
  bluenviron/mediamtx:1.21.3-ffmpeg \
  -v error -show_entries format=duration:stream=codec_name,width,height,avg_frame_rate \
  -of default=noprint_wrappers=1 /s/person-bicycle-car-detection.mp4

实测回显:

codec_name=h264
width=768
height=432
avg_frame_rate=12/1
codec_name=aac
avg_frame_rate=0/0
duration=53.916667

4.3 编写 Viseron 配置文件

Viseron 的全部行为由 /config/config.yaml 驱动,组件化配置:用什么组件就写什么组件的配置段。创建 config/config.yaml(本篇实测配置,摄像头/运动检测/物体检测/录像全链路):

ffmpeg:
  camera:
    fake_camera:
      name: Fake Camera
      host: mediamtx
      port: 8554
      path: /cam
      stream_format: rtsp
      fps: 12
      recorder:
        idle_timeout: 5

mog2:
  motion_detector:
    cameras:
      fake_camera:
        fps: 2

darknet:
  object_detector:
    model_path: /detectors/models/darknet/yolov7-tiny.weights
    model_config: /detectors/models/darknet/yolov7-tiny.cfg
    cameras:
      fake_camera:
        fps: 2
        scan_on_motion_only: false
        labels:
          - label: person
            confidence: 0.7
            trigger_event_recording: true
          - label: bicycle
            confidence: 0.7
            trigger_event_recording: true
          - label: car
            confidence: 0.7
            trigger_event_recording: true

nvr:
  fake_camera:

webserver:
  auth:
    session_expiry:
      days: 7

logger:
  default_level: info

配置逐项说明:

  • ffmpeg.camera.fake_camera:摄像头接入段。host/port/path 组成 RTSP 地址 rtsp://mediamtx:8554/cam(Compose 网络内服务名 mediamtx 即主机名);stream_format: rtsp 用默认 RTP 传输;fps: 12 按源视频帧率全量取帧;recorder.idle_timeout: 5 表示事件结束后 5 秒无新目标即停止录像。
  • mog2.motion_detector:运动检测组件(MOG2 高斯混合背景建模),按摄像头配置检测帧率 fps: 2——运动检测很廉价,低帧率足够。
  • darknet.object_detector:Darknet(YOLO)物体检测组件。model_path/model_config 指向镜像内置的 yolov7-tiny 模型;fps: 2 为检测帧率;scan_on_motion_only: false 表示不做「仅运动时扫描」(测试源画面持续变化,关掉以免漏检);labels 列出要跟踪的三类目标,confidence: 0.7 为置信度阈值,trigger_event_recording: true 表示命中即触发事件录像。
  • nvr.fake_camera:NVR 协调组件按摄像头启用——官方文档明确这是必选组件,没有它 Viseron 不会做任何事。
  • webserver.auth:Web 认证。不写 auth: 子配置时认证默认关闭;本篇演示启用并将会话有效期设为 7 天,首次启动后需在 Web 界面完成管理员账号初始化(见 4.7)。
  • logger.default_level: info:日志级别。

4.4 编写 docker-compose.yml

创建 /opt/viseron/docker-compose.yml(显式声明项目名 viseron-3.7.0-stack,避免与其他项目的同名服务互相干扰):

name: viseron-3.7.0-stack

services:
  viseron:
    image: roflcoopter/viseron:3.7.0
    container_name: viseron-3.7.0-nvr
    restart: unless-stopped
    shm_size: "1024mb"
    ports:
      - "8151:8888"
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - ../config:/config
      - ../segments:/segments
      - ../snapshots:/snapshots
      - ../thumbnails:/thumbnails
      - ../event_clips:/event_clips
      - ../timelapse:/timelapse
      - /etc/localtime:/etc/localtime:ro
    networks:
      viseron-3.7.0-net:
        aliases:
          - viseron

  mediamtx:
    image: bluenviron/mediamtx:1.21.3-ffmpeg
    container_name: viseron-3.7.0-mediamtx
    restart: unless-stopped
    ports:
      - "8150:8554"
    networks:
      viseron-3.7.0-net:
        aliases:
          - mediamtx

  camsource:
    image: bluenviron/mediamtx:1.21.3-ffmpeg
    container_name: viseron-3.7.0-camsource
    restart: unless-stopped
    entrypoint: ["ffmpeg"]
    command:
      - -hide_banner
      - -re
      - -stream_loop
      - "-1"
      - -i
      - /source/person-bicycle-car-detection.mp4
      - -c:v
      - libx264
      - -preset
      - veryfast
      - -tune
      - zerolatency
      - -g
      - "30"
      - -b:v
      - 1500k
      - -maxrate
      - 1500k
      - -bufsize
      - 3000k
      - -pix_fmt
      - yuv420p
      - -f
      - rtsp
      - rtsp://mediamtx:8554/cam
    volumes:
      - ../source:/source:ro
    depends_on:
      - mediamtx
    networks:
      viseron-3.7.0-net:
        aliases:
          - camsource

networks:
  viseron-3.7.0-net:
    name: viseron-3.7.0-net
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.61.0/24

关键点解读:

  • camsource 就是模拟摄像头:entrypoint 覆盖为 ffmpeg,-re 按原速读文件、-stream_loop -1 无限循环,转码 1500k 码率后推到 rtsp://mediamtx:8554/cam。等价的命令行形式(便于理解,实际部署用上面的 compose):
ffmpeg -re -stream_loop -1 -i /source/person-bicycle-car-detection.mp4 \
  -c:v libx264 -preset veryfast -tune zerolatency -g 30 \
  -b:v 1500k -maxrate 1500k -bufsize 3000k -pix_fmt yuv420p \
  -f rtsp rtsp://mediamtx:8554/cam
  • shm_size: 1024mb:Viseron 用共享内存存放解码帧,官方安装文档的 docker run 与 compose 示例均固定写 1024mb,本篇沿用。
  • 端口映射:8151(Web UI + REST API,容器内 8888)、8150(MediaMTX RTSP,仅调试用可不开)。Viseron 的 PostgreSQL(5432)与 go2rtc(8554/8555/1984)都只在容器内部使用,不映射到宿主机。
  • 数据持久化:六个数据目录全部挂载到部署目录下(见第五章),元数据库落在 /config/postgresql。
  • 网络:固定子网 10.89.61.0/24(自定义网段避免与其他 Docker 网段冲突;读者环境如冲突可换空闲网段)。viseron/mediamtx/camsource 三服务通过别名互相解析。
  • TZ=Asia/Shanghai:时区注入。实测首启日志中 PostgreSQL 以 default time zone ... Asia/Shanghai 初始化,事件时间戳与 Web 界面时间均按此时区显示。

4.5 启动与状态确认

cd /opt/viseron
docker compose up -d
docker compose ps

实测回显:

[+] Running 4/4
 ✔ Network viseron-3.7.0-net     Created
 ✔ Container viseron-3.7.0-camsource  Started
 ✔ Container viseron-3.7.0-mediamtx   Started
 ✔ Container viseron-3.7.0-nvr        Started
NAME                      IMAGE                               COMMAND                  SERVICE     CREATED          STATUS          PORTS
viseron-3.7.0-camsource   bluenviron/mediamtx:1.21.3-ffmpeg   "ffmpeg -hide_banner…"   camsource   21 minutes ago   Up 21 minutes
viseron-3.7.0-mediamtx    bluenviron/mediamtx:1.21.3-ffmpeg   "/mediamtx"              mediamtx    21 minutes ago   Up 21 minutes   0.0.0.0:8150->8554/tcp, [::]:8150->8554/tcp
viseron-3.7.0-nvr         roflcoopter/viseron:3.7.0           "/init"                  viseron     21 minutes ago   Up 16 minutes   0.0.0.0:8151->8888/tcp, [::]:8151->8888/tcp

三个服务全部 Up。查看 MediaMTX 日志确认模拟摄像头的流已就绪:

docker logs viseron-3.7.0-mediamtx 2>&1 | head -13

实测回显:

2026/10/30 02:09:32 INF MediaMTX v1.21.3, linux, amd64
2026/10/30 02:09:32 INF configuration loaded from /mediamtx.yml
2026/10/30 02:09:32 INF [RTSP] started with listeners on :8554 (TCP/RTSP), :8000 (UDP/RTP), :8001 (UDP/RTCP)
2026/10/30 02:09:32 INF [RTMP] started with listener on :1935 (TCP/RTMP)
2026/10/30 02:09:32 INF [HLS] started with listener on :8888 (TCP/HTTP)
2026/10/30 02:09:32 INF [WebRTC] started with listeners on :8889 (TCP/HTTP), :8189 (UDP/ICE)
2026/10/30 02:09:32 INF [SRT] started with listener on :8890 (UDP/SRT)
2026/10/30 02:09:32 WAR [MoQ] certificate auto.key not found, generating it from scratch
2026/10/30 02:09:32 INF [MoQ] started with listeners on :8892 (TCP/HTTP2), :8892 (UDP/HTTP3), :8893 (UDP/QUIC)
2026/10/30 02:09:33 INF [RTSP] [conn 10.89.61.3:46942] opened
2026/10/30 02:09:33 INF [RTSP] [session aa9db21f] created by 10.89.61.3:46942
2026/10/30 02:09:33 INF [path cam] stream is available and online, 2 tracks (H264, MPEG-4 Audio)
2026/10/30 02:09:33 INF [RTSP] [session aa9db21f] is publishing to path 'cam'

[path cam] stream is available and online, 2 tracks (H264, MPEG-4 Audio) 表示 cam 路径已有 H.264 视频 + AAC 音频两路轨道在线;随后 conn 10.89.61.4(Viseron 主服务)开始 reading from path 'cam',说明 Viseron 已拉流成功。

查看 Viseron 主服务日志,确认内置 PostgreSQL 初始化与组件装配:

docker logs viseron-3.7.0-nvr 2>&1 | grep -E "Initializing Viseron|Setup of component|Setup of domain|Viseron initialized|Starting recorder|Starting motion" | head -16

实测回显:

2026-10-30 10:10:12.696 [INFO    ] [viseron.core] - Initializing Viseron 3.7.0
2026-10-30 10:10:12.700 [INFO    ] [viseron.components] - Setting up component data_stream
2026-10-30 10:10:12.700 [INFO    ] [viseron.components] - Setting up component logger
2026-10-30 10:10:12.703 [INFO    ] [viseron.components] - Setting up component storage
2026-10-30 10:10:12.791 [INFO    ] [viseron.components] - Setup of component storage took 0.1 seconds
2026-10-30 10:10:12.795 [INFO    ] [viseron.components] - Setting up component webserver
2026-10-30 10:10:12.795 [INFO    ] [viseron.components] - Setting up component mog2
2026-10-30 10:10:12.797 [INFO    ] [viseron.components] - Setting up component nvr
2026-10-30 10:10:12.798 [INFO    ] [viseron.components] - Setting up component darknet
2026-10-30 10:10:12.800 [INFO    ] [viseron.components] - Setting up component ffmpeg
2026-10-30 10:10:18.834 [INFO    ] [viseron.components.nvr.nvr.fake_camera] - NVR for camera Fake Camera initialized
2026-10-30 10:10:18.840 [INFO    ] [viseron.core] - Viseron initialized in 6.1 seconds
2026-10-30 10:10:29.930 [INFO    ] [viseron.components.ffmpeg.recorder.fake_camera] - Starting recorder
2026-10-30 10:10:29.945 [INFO    ] [viseron.components.nvr.nvr.fake_camera] - Starting motion detector

Viseron initialized in 6.1 seconds 表示配置校验、PostgreSQL 连接、五个组件与四个 domain 全部装配完成;Starting recorder / Starting motion detector 说明首个事件录像已被目标命中触发。首次启动还会看到 PostgreSQL 的初始化过程,实测回显(输出节选,实测首尾):

[cont-init.d] 80-postgres: executing...
PostgreSQL major version: 16
PostgreSQL data dir: /config/postgresql
Database has not been initialized. Initializing...
The files belonging to this database system will be owned by user "postgres".
...
Success. You can now start the database server using:

    /usr/lib/postgresql/16/bin/pg_ctl -D /config/postgresql -l logfile start

Starting PostgreSQL...
2026-10-30 10:10:10.349 CST [569] LOG:  starting PostgreSQL 16.15 (Ubuntu 16.15-0ubuntu0.24.04.1) on x86_64-pc-linux-gnu

4.6 检测与录像验证

等待约 1 分钟(视频里行人反复入画,必出事件),先验证落盘产物。录像分片、事件缩略图、检测快照分别落盘:

ls -la /opt/viseron/segments/fake_camera/ | tail -4
ls -la /opt/viseron/thumbnails/fake_camera/ | tail -3
find /opt/viseron/snapshots -name "*.jpg" | head -3

实测回显:

-rw-r--r-- 1 root root  779989 Oct 30 10:46 1793328409.m4s
-rw-r--r-- 1 root root 1108573 Oct 30 10:46 1793328414.m4s
-rw-r--r-- 1 root root  946740 Oct 30 10:47 1793328419.m4s
-rw-r--r-- 1 root root    1364 Oct 30 10:47 init.mp4
-rw-r--r-- 1 root root  87418 Oct 30 10:32 98.jpg
-rw-r--r-- 1 root root 103135 Oct 30 10:32 99.jpg
-rw-r--r-- 1 root root  98388 Oct 30 10:47 latest_thumbnail.jpg
/opt/viseron/snapshots/object_detector/fake_camera/2026-10-30-02-36-25-6950da06-6771-4296-aa23-c61f7d1318fa.jpg
/opt/viseron/snapshots/object_detector/fake_camera/2026-10-30-02-43-17-d16a1584-d01c-47ab-b24f-ce5c444d7c5c.jpg
/opt/viseron/snapshots/object_detector/fake_camera/latest_snapshot.jpg

segments/ 下是 fMP4 录像分片(init.mp4 为初始化段)、thumbnails/ 下按录像 ID 存事件缩略图、snapshots/object_detector/ 下按时间戳存目标快照——录像与快照链路均已工作。

再通过 REST API 验证服务可用性。本篇配置启用了认证,接口需带凭据访问;最省事的方式是在 Web UI(登录后右上角 Profile 页)创建一个个人访问令牌(PAT,vpat_ 前缀),之后命令行直连接口。创建与登录的完整机制见本专栏《Viseron 3.7.0 API 使用详解》,这里直接用实测得到的 PAT 验证:

curl -s http://127.0.0.1:8151/api/v1/cameras \
  -H 'Authorization: Bearer vpat_349eaef4874966c72a33893935aed8c559d3caafdfe93a809723d0d9565300623c8daf0db165fef17862b5d39304be5e973c0e8dfd9ab9844c163e9fb55e1283'

实测回显(该 PAT 为一次性演示令牌,验证后已删除):

{"fake_camera": {"identifier": "fake_camera", "name": "Fake Camera", "width": 768, "height": 432, "access_token": "0c4d09cb89d7c3c7342a7f6a8aea4bd229c4db89e2eb943094c636adb100e37b25a5e50971760e7eb919ff82c3f910dbd3b494571ee4dbba310f74f9e6b0588d", "mainstream": {"width": 768, "height": 432}, "still_image": {"refresh_interval": 10, "available": true, "width": 768, "height": 432}, "is_on": true, "connected": true, "live_stream_available": false, "is_recording": false, "ptz_support": null}}

connected: true 表示摄像头在线。事件统计接口(POST 方式)的实测回显:

{"events_amount": {"2026-10-30": {"motion": 25, "recording": 65, "object": 34}}}

运动事件 25 条、录像事件 65 段、目标检测事件 34 条——检测/录像全链路端到端跑通。

4.7 Web UI 初始化与登录

浏览器访问 http://<服务器IP>:8151。本篇配置启用了认证(webserver.auth),首次访问会进入初始化引导页,按提示创建管理员账号——本篇演示账号定为 admin / q1w2e3r4。创建完成后即进入主界面:左侧摄像头实时画面,Events 页查看事件缩略图与录像回放。若配置中未写 auth: 子配置,Web 界面与 API 均为免登录直连(默认行为),生产环境建议启用认证。

五、数据持久化说明

挂载宿主目录(本文)容器内路径内容
配置/opt/viseron/config/configconfig.yaml + postgresql/(元数据库,含事件/录像索引)
录像分片/opt/viseron/segments/segmentsfMP4 分片(init.mp4 + 按 epoch 命名的 .m4s)
检测快照/opt/viseron/snapshots/snapshotsmotion_detector/object_detector 等按域分子目录
事件缩略图/opt/viseron/thumbnails/thumbnails按录像 ID 命名的事件封面 jpg
事件片段/opt/viseron/event_clips/event_clips事件级剪辑
延时摄影/opt/viseron/timelapse/timelapsetimelapse 域产物

注意:Viseron 的事件、录像、文件索引元数据全部存放在 /config/postgresql 内的 PostgreSQL 16 数据目录——备份 /config 目录即等于备份全部元数据(分片/快照等大文件在各自独立目录,可分层备份)。

验证持久化:重启整个栈后事件与录像仍在——

cd /opt/viseron
docker compose down && docker compose up -d
sleep 60
ls /opt/viseron/segments/fake_camera/ | head -3
ls /opt/viseron/thumbnails/fake_camera/ | wc -l

实测回显(down/up 后历史分片与缩略图完好,且新事件继续落盘):

1793326220.m4s
1793326228.m4s
1793326232.m4s
105

六、环境变量表

Viseron 官方镜像常用环境变量(本篇实测验证项):

变量默认值说明本篇取值
TZ宿主时区时区;实测首启日志 PostgreSQL 以 default time zone ... Asia/Shanghai 初始化,事件时间戳随之Asia/Shanghai
VISERON_DISABLE_CHOWN未设置(空)3.7.0 新增。设为任意非空值时跳过启动阶段的目录属主修正。实测未设置时启动日志明确输出 VISERON_DISABLE_CHOWN is not enabled, applying ownership changes for volume paths未设置(保持属主修正)

💡 技术拓展:VISERON_DISABLE_CHOWN 什么时候该开——

场景建议原因
本地磁盘/常规卷不开(默认)属主修正保证读写权限正确
NFS/CIFS 网络存储开分布式文件系统上 chown 全量递归极慢甚至失败
只读挂载开chown 在只读卷上必然报错

本篇数据全部落本地盘,保持默认行为。

七、配置参数说明与配置文件挂载

部署相关的核心配置项汇总(完整配置参数的逐项修改-验证闭环见本专栏《Viseron 3.7.0 配置参数详解》):

配置项作用本篇实测验证方式
ffmpeg.camera.<名称>.host/port/path摄像头 RTSP 地址三要素MediaMTX 日志 reading from path 'cam'
ffmpeg.camera.<名称>.recorder.idle_timeout事件结束后延录秒数日志 Stopping recording in: 5s 倒计时
mog2.motion_detector.cameras.<名称>.fps运动检测帧率events 统计中 motion 事件增长
darknet.object_detector.model_path/model_config检测模型文件路径启动日志 object_detector domain setup 成功 + object 事件
darknet.object_detector.cameras.<名称>.labels[].confidence/trigger_event_recording置信度阈值与命中触发录像person/bicycle/car 事件产生录像
nvr.<名称>摄像头的 NVR 协调(必选)日志 NVR for camera Fake Camera initialized
webserver.authWeb/API 认证开关未配置时接口 401 与 200 行为差异
logger.default_level全局日志级别日志输出为 INFO 级

配置文件挂载即 4.4 的 ../config:/config:修改 config/config.yaml 后重启主服务生效。Viseron 的 Web UI 内置配置编辑器(左侧 Configuration 页),保存后同样触发重载,日常改配置可以不登服务器。

八、等价 docker run

不用 Compose 时的等价单命令(便于理解各服务参数;生产推荐 Compose):

# RTSP 流服务器(模拟摄像头服务端)
docker run -d --name viseron-3.7.0-mediamtx \
  -p 8150:8554 \
  bluenviron/mediamtx:1.21.3-ffmpeg

# 模拟摄像头推流
docker run -d --name viseron-3.7.0-camsource \
  --entrypoint ffmpeg \
  -v /opt/viseron/source:/source:ro \
  --network container:viseron-3.7.0-mediamtx \
  bluenviron/mediamtx:1.21.3-ffmpeg \
  -re -stream_loop -1 -i /source/person-bicycle-car-detection.mp4 \
  -c:v libx264 -preset veryfast -tune zerolatency -g 30 \
  -b:v 1500k -maxrate 1500k -bufsize 3000k -pix_fmt yuv420p \
  -f rtsp rtsp://127.0.0.1:8554/cam

# Viseron 主服务
docker run -d --name viseron-3.7.0-nvr \
  --shm-size=1024mb \
  -e TZ=Asia/Shanghai \
  -p 8151:8888 \
  -v /opt/viseron/config:/config \
  -v /opt/viseron/segments:/segments \
  -v /opt/viseron/snapshots:/snapshots \
  -v /opt/viseron/thumbnails:/thumbnails \
  -v /opt/viseron/event_clips:/event_clips \
  -v /opt/viseron/timelapse:/timelapse \
  -v /etc/localtime:/etc/localtime:ro \
  roflcoopter/viseron:3.7.0

⚠️ 等价命令未包含自定义网络与别名,独立运行的容器间需用 IP 或 --link 方式互通(camsource 上面用 --network container: 共享 mediamtx 网络栈绕开了这一问题,但 Viseron 主服务访问 mediamtx 时 host 不能再写服务名 mediamtx,需写 127.0.0.1 并让 config.yaml 的 host 同步调整),因此生产环境仍以 Compose(自带内部 DNS)为准。

九、常用运维命令

cd /opt/viseron
docker compose ps                  # 三服务状态
docker compose logs -f viseron     # 跟踪 Viseron 主服务日志
docker compose restart viseron     # 修改 config.yaml 后重启生效
docker compose stop camsource      # 停掉模拟摄像头(Viseron 显示摄像头离线)
docker compose start camsource     # 恢复推流
docker compose down                # 停止并移除栈(数据在挂载目录不受影响)
docker compose up -d               # 重新拉起

升级到新版本:修改 docker-compose.yml 中 viseron 镜像 tag 为目标版本(如 3.8.0),执行:

docker compose pull viseron && docker compose up -d viseron

Viseron 内置的数据库迁移由 alembic 驱动,实测首启日志可见 Running stamp_revision -> 7f6d3739fcd6,升级时元数据 schema 自动迁移,无需手工干预。

十、常见问题

Q1:启动报 Bind for 0.0.0.0:8151 failed: port is already allocated? 端口被其他进程/其他 compose 项目占用。ss -ltnp | grep 8151 找到占用者,或换用空闲端口(本文约定 8128-8152 段内取空闲者)。

Q2:首次启动卡在 PostgreSQL 初始化是不是故障? 不是。首次启动镜像要完成 PostgreSQL 集群初始化(initdb、建库、属主修正),实测该阶段日志为 Database has not been initialized. Initializing... 到 PostgreSQL Server has started!,随后 Viseron initialized in 6.1 seconds。之后每次重启直接复用 /config/postgresql 数据目录,启动速度明显加快。

Q3:数据目录放在 NFS 上,启动极慢或卡在属主修正? 启动阶段默认对全部挂载卷递归执行属主修正(日志 Changing ownership of files to abc:abc, this may take a while...),NFS 大目录上这一步可能耗时极长。给服务加环境变量 VISERON_DISABLE_CHOWN=1 跳过(3.7.0 新增),并保证挂载本身可读写。

Q4:接口返回 {"status": 401, "error": "Authentication required"}? 配置了 webserver.auth 后所有 API 需认证。快速验证链路:浏览器登录后在 Profile 页创建 PAT,请求带 Authorization: Bearer <vpat_ 前缀令牌> 头即可;或临时在 config.yaml 注释掉 auth: 子配置并重启恢复免认证。完整认证机制(XSRF/JWT/PAT)见本专栏《Viseron 3.7.0 API 使用详解》。

Q5:拉取镜像太慢或失败? roflcoopter/viseron:3.7.0 约 9.45GB,直连 Docker Hub 缓慢时可为 Docker daemon 配置镜像加速或代理;3.7.0 起官方同步发布 GHCR,也可把镜像名换成 ghcr.io/roflcoopter/viseron:3.7.0 走另一条通道。

Q6:想接入真实摄像头? 把 ffmpeg.camera.fake_camera 下的 host/port/path 换成摄像头的 RTSP 地址三要素(如 Hikvision 常见 host: 摄像头IP、port: 554、path: /Streaming/Channels/101/,并按摄像头实际凭据补 username/password 字段),nvr:、mog2、darknet 下方的摄像头标识同步改名,然后删除 camsource 服务即可。3.7.0 起也可用 ONVIF 组件自动发现摄像头。

Q7:检测模型文件从哪来? 官方镜像内置 Darknet 模型于 /detectors/models/darknet/(含默认模型与本文用的 yolov7-tiny),model_path/model_config 直接写容器内路径即可,无需手工下载;换用自定义模型时把权重文件挂载进容器并修改这两个路径。

十一、参考链接