Frigate 贡献者开发指南:从本地环境搭建到提交 PR 的完整实践
Frigate 贡献者开发指南:从本地环境搭建到提交 PR 的完整实践
Frigate 是一套面向 IP 摄像头的实时本地目标检测 NVR 系统,其代码库横跨 Python 后端、Web 前端(Preact/Vite)与 Docker 多架构构建体系。本文基于仓库内 docs/docs/development/contributing.md 开发贡献文档,系统讲解如何获取源码、搭建与核心/Web/文档三个子项目匹配的开发环境、运行测试、执行硬件加速验证、通过格式化与静态类型检查,直至提交 Pull Request 并参与官方多架构构建的完整流程。读完本文,你将具备在本仓库内独立开展 Frigate 后端、前端或文档开发,并顺利通过 CI 检查的实战能力。
一、获取源码:分清三个独立仓库
Frigate 的开发工作分散在三个仓库中,本文档所指向的主仓库只包含核心应用本体及其依赖。
核心、Web、Docker 与文档(本仓库)
本仓库持有 Frigate 主应用及全部依赖(Python 后端、Web UI、Dockerfile、文档站点)。开发流程为:先 fork 上游的 blakeblackshear/frigate 仓库到自己的 GitHub 账户,再将 fork 后的仓库 clone 到本地。此后按下面三个方向分别阅读对应小节:
Frigate Home Assistant App(独立仓库)
该仓库承载 Home Assistant App,用于在 Home Assistant OS 及兼容安装环境中,让你能够从 Home Assistant Supervisor 选项卡直接运行 Frigate。需要 fork 并 clone blakeblackshear/frigate-hass-addons 仓库。
Frigate Home Assistant Integration(独立仓库)
该仓库保存自定义集成,无论 Frigate 是作为独立 Docker 容器运行,还是作为上述 Home Assistant App 运行,它都能让 Home Assistant 自动为你的 Frigate 实例创建实体。需 fork 并 clone blakeblackshear/frigate-hass-integration 仓库。
二、核心后端开发环境搭建
前置条件
- GNU make(用于调用 Makefile 中的构建目标);
- Docker(含 buildx 插件);
- 可选的额外检测器(Coral、OpenVINO 等),建议配备以模拟真实运行性能。
需要注意:一个 Coral 设备同一时刻只能被单个进程使用,因此如果开发过程中需要使用 Coral,建议准备额外的 Coral 设备,避免与正在运行的 Frigate 实例冲突。
第 1 步:用 Visual Studio Code 打开仓库
打开仓库后,VS Code 会提示你“在远程容器中重新打开”项目。这一步会基于 Frigate 基础容器构建一个包含全部开发依赖的开发容器,从而保证所有贡献者使用一致的开发环境,无需在宿主机上安装任何依赖。
该开发容器在 docker/main/Dockerfile 中有清晰定义:它从 deps 阶段派生 devcontainer 目标,安装 Node 20 与 make,将工作区挂载到 /workspace/frigate,并把源码符号链接到 /opt/frigate/frigate(go2rtc 的 create_config.sh 会引用该路径)。值得留意的是,开发容器默认不会启动真正的 Frigate 服务,而是由 docker/main/fake_frigate_run 脚本模拟一个空转服务(每 5 秒打印一条 [INFO] The fake Frigate service is running...),用于模拟日志输出,真正的后端由你手动启动。
第 2 步:编写本地测试配置
在仓库根目录创建 config/config.yml。文档给出的示例配置如下(可按需修改):
mqtt:
host: mqtt
cameras:
test:
ffmpeg:
inputs:
- path: /media/frigate/car-stopping.mp4
input_args: -re -stream_loop -1 -fflags +genpts
roles:
- detect
input_args 中 -re 按原始帧率读取、-stream_loop -1 无限循环播放 mp4 文件,-fflags +genpts 用于修正时间戳。这里的输入可以是任何合法的 ffmpeg 输入源。
第 3 步:准备测试用的 mp4 文件
在仓库根目录创建 debug 文件夹并放入测试视频。这个目录同时是你在测试配置中开启录像功能后录像文件的落盘位置。修改第 2 步的配置指向正确的视频文件,并查看仓库根目录的 docker-compose.yml 了解卷映射关系——其中 ./config:/config 与 ./debug:/media/frigate 两条映射正是让配置文件与视频文件进入容器的关键。
第 4 步:从命令行运行 Frigate
VS Code 会自动为你启动 Docker Compose 文件并打开一个连接到 frigate-dev 容器的终端:
- 根据开发所用硬件,你可能需要修改根目录的 docker-compose.yml 来透传 USB Coral 或 GPU 以实现硬件加速。该文件已预置了相关注释:
group_add需要与宿主机render/video/plugdev组 ID 一致(否则 OpenVINO GPU 加速会失败),并给出了 NVIDIA GPU(deploy.resources.reservations)与设备透传(/dev/bus/usb、/dev/dri)的示例; - 在容器终端执行
python3 -m frigate启动后端; - 另开一个终端,进入
web目录执行npm install && npm run dev启动前端。
第 5 步:清理(Teardown)
关闭 VS Code 后容器可能仍在运行。执行 docker-compose down -v 即可彻底关闭并清理全部容器。
补充:Makefile 中的常用构建目标
仓库根目录 Makefile 提供了一系列可直接复用的目标,适合不依赖 VS Code 的开发方式:
make local:构建frigate:latest本地镜像(--target=frigate且--load);make debug:以DEBUG=true构建,附带开发依赖;make amd64/make arm64/make build:按平台构建镜像;make run:构建后直接以-p 5000:5000 -p 8971:8971运行并挂载./config;make run_tests:在容器内依次执行python3 -u -m unittest与 mypy 类型检查,与下文测试、检查命令一一对应。
三、测试:单元测试与硬件加速验证
单元测试
GitHub 会在新 PR 上执行单元测试,因此在提交前必须确保全部测试通过:
python3 -u -m unittest
仓库的单元测试集中在 frigate/test 目录下,覆盖 HTTP API、MQTT、PTZ 自动追踪、运动检测、录像保留策略、WebSocket 鉴权、sqlite-vec 嵌入等多个模块,例如 test_ptz_autotrack.py、test_detection_runners.py、test_http_media.py 等,可作为编写新测试时的参考模板。
FFmpeg 硬件加速验证
以下命令在容器内执行,用于确认硬件加速正常工作(文档特别提醒:Raspberry Pi 场景下应观察到 top 中 CPU 占用低于 50%,去掉 -c:v h264_v4l2m2m 后约 80% CPU):
Raspberry Pi(64 位)
ffmpeg -c:v h264_v4l2m2m -re -stream_loop -1 -i https://streams.videolan.org/ffmpeg/incoming/720p60.mp4 -f rawvideo -pix_fmt yuv420p pipe: > /dev/null
NVIDIA GPU
ffmpeg -c:v h264_cuvid -re -stream_loop -1 -i https://streams.videolan.org/ffmpeg/incoming/720p60.mp4 -f rawvideo -pix_fmt yuv420p pipe: > /dev/null
NVIDIA Jetson
ffmpeg -c:v h264_nvmpi -re -stream_loop -1 -i https://streams.videolan.org/ffmpeg/incoming/720p60.mp4 -f rawvideo -pix_fmt yuv420p pipe: > /dev/null
VAAPI(Intel 核显等)
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format yuv420p -re -stream_loop -1 -i https://streams.videolan.org/ffmpeg/incoming/720p60.mp4 -f rawvideo -pix_fmt yuv420p pipe: > /dev/null
QSV(Intel 快速同步视频)
ffmpeg -c:v h264_qsv -re -stream_loop -1 -i https://streams.videolan.org/ffmpeg/incoming/720p60.mp4 -f rawvideo -pix_fmt yuv420p pipe: > /dev/null
这些解码器参数与 Frigate 官方镜像内置的 ffmpeg 构建保持一致,可用作排查硬件加速是否生效的快速基准。
四、提交 Pull Request 前的三道检查
代码必须通过格式化、Lint 与类型检查,GitHub 会在 PR 上自动执行这些检查,因此强烈建议在提交前本地先行运行。
格式化(ruff format)
ruff format frigate migrations docker *.py
Lint(ruff check)
ruff check frigate migrations docker *.py
Ruff 的规则配置位于 pyproject.toml:target-version = "py311",忽略 E501(行长)等规则,并额外启用了 I(导入排序)、UP(pyupgrade)、G(日志格式)、ASYNC210、B904 等检查族。
MyPy 静态类型检查
python3 -u -m mypy --config-file frigate/mypy.ini frigate
pyproject.toml 中针对 Python 后端的 mypy 配置相当严格(位于 frigate/mypy.ini):python_version = 3.11、disallow_untyped_defs = true、warn_unreachable = true、strict_equality = true、check_untyped_defs = true 等。同时,为逐步推进类型覆盖,配置对 frigate.api.*、frigate.detectors.*、frigate.util.*、frigate.video.* 等若干模块暂设 ignore_errors = true(注释中标注为 TODO,待后续补充类型注解后移除)。
五、Web 前端开发
前置条件
- 全部核心后端前置条件(或者本机已有另一个可访问的 Frigate 实例);
- Node.js 20(开发容器镜像中已通过
nsolid_setup_deb.sh 20安装)。
修改流程
第 1 步:准备一个 Frigate 实例
Web UI 需要连接一个 Frigate 实例才能获取全部数据。可以本地运行一个实例(推荐),也可以连接网络上独立的实例。本地实例的搭建方式见核心后端开发环境搭建。如果你不会改动 Frigate 的 HTTP API,则可以跳过本步,直接按“第 3a 步”将开发服务器指向网络上的任意 Frigate 实例。
第 2 步:安装依赖
cd web && npm install
第 3 步:启动开发服务器
cd web && npm run dev
第 3a 步:连接非本机实例
将 web/vite.config.ts 中的代理目标 localhost:5000 替换为远端后端服务器的 IP。该文件通过 server.proxy 将 /api、/vod、/clips、/exports(HTTP)以及 /ws、/live(WebSocket)统一代理到后端,因此前端开发时无需处理跨域。其默认值来自 process.env.PROXY_HOST || "localhost:5000",也可以直接用环境变量 PROXY_HOST 指定目标地址。
第 4 步:修改代码
Web UI 基于 Vite、Preact 与 Tailwind CSS 构建。以下是官方给出的轻量原则与建议:
- 避免新增依赖。Web UI 追求轻量与快速加载;
- 不要做大范围改动。任何大型或架构级想法都应先在讨论区发起讨论;
- 确保
lint通过,该命令会尽可能自动修复风格问题(含 Prettier 格式化):
npm run lint
- 补充单元测试并确保通过。应尽量在每次改动时提高测试覆盖率,防止功能在未来被意外破坏:
npm run test
- 在不同浏览器(Firefox、Chrome、Safari)中测试——它们各有独特的行为差异。
前端测试脚本定义在 web/package.json:test 使用 vitest(配置见 web/vite.config.ts 的 test 段,基于 jsdom、mockReset/restoreMocks、全局模式),lint 还会额外检查 e2e 规范(node e2e/scripts/lint-specs.mjs),e2e 测试则基于 Playwright(web/e2e/playwright.config.ts)。如果运行测试时遇到形如 TypeError: Cannot read properties of undefined (reading 'context') 的错误,可能是 vitest 的已知问题(相关 issue:vitest#1910、vitest#1652),官方文档也坦承尚未完全解决。
六、文档站点开发
前置条件
- Node.js 20。
修改流程
第 1 步:安装依赖
cd docs && npm install
第 2 步:本地开发
npm run start
该命令会启动本地开发服务器并打开浏览器窗口,大部分改动可即时热更新,无需重启服务器。文档基于 Docusaurus v3 构建(参见 docs/package.json,依赖 @docusaurus/core、@docusaurus/preset-classic、docusaurus-plugin-openapi-docs 等),修改 Frigate 文档前建议先熟悉 Docusaurus 官方文档。值得注意的是 start 脚本会先执行 npm run build:config 与 npm run regen-docs(重新生成 API 文档),因此首次启动会稍慢。
第 3 步:构建(可选)
npm run build
该命令将静态内容生成到 build 目录,可部署到任意静态内容托管服务。文档站点的导航、侧边栏配置位于 docs/sidebars.ts 与 docs/docusaurus.config.ts。
七、官方多架构镜像构建
若需构建并推送官方多架构镜像,先在宿主机配置 buildx 多架构支持:
docker buildx stop builder && docker buildx rm builder # <---- 如果已存在
docker run --privileged --rm tonistiigi/binfmt --install all
docker buildx create --name builder --driver docker-container --driver-opt network=host --use
docker buildx inspect builder --bootstrap
make push
其中 make push 对应 Makefile 中的 push 目标:它会针对 linux/arm64/v8,linux/amd64 双平台构建 --target=frigate 的镜像并推送(标签为 ${GITHUB_REF_NAME}-$(COMMIT_HASH))。仓库还通过 docker/*/*.mk 将各硬件平台的构建目标(如 RPi、Rockchip、TensorRT、ROCM 等)注入主 Makefile。若要为新的单板计算机/检测器添加社区支持,可参考 docs/docs/development/contributing-boards.md,其中说明了 board.hcl(Bake 文件)、board.mk、Dockerfile(以 deps 为基底 + COPY --from=rootfs / /)以及 CI 与 CODEOWNERS 的必改项。
八、开发容器内的 Nginx 配置调试
在开发容器中测试 nginx 配置改动时,无需重建容器即可复制并重载配置:
sudo cp docker/main/rootfs/usr/local/nginx/conf/* /usr/local/nginx/conf/ && sudo /usr/local/nginx/sbin/nginx -s reload
该命令将仓库中的 nginx 配置(位于 docker/main/rootfs/usr/local/nginx/conf)复制进容器内的 nginx 配置目录并执行热重载,适用于验证代理、鉴权等 nginx 层改动的场景。
九、参与 Web UI 翻译
Frigate 使用 Weblate 管理 Web UI 的多语言翻译。参与方式:在 Weblate 注册账户后进入 Frigate NVR 项目。翻译时需保持既有 key 结构不变,只翻译 value;同时确保翻译保留正确的格式,包括占位符变量(如 {{example}})。本仓库的翻译产物即 web/public/locales/ 下的各语言 JSON 文件,可作为理解 key 结构的参考。
结语
从 fork 源码、启动 VS Code 开发容器、编写 config/config.yml 与 debug 测试视频,到运行 python3 -m frigate 起后端、npm run dev 起前端,再到用 ruff、mypy、unittest 完成 PR 前的自检——本文已覆盖 Frigate 核心、Web、文档三大子项目的完整开发闭环。无论是修复后端 bug、为 Web UI 增加功能,还是补充文档与翻译,遵循上述流程都能确保你的改动与官方 CI 检查及多架构发布体系无缝衔接。