Files
StudyDiary-20261009/02-学习笔记/NAS(群晖+飞牛)MoviePilot_TMM TMDB刮削 终极稳定技术方案.md
CrazyJasonwell e97be9ac8c commit all
2026-10-09 22:06:40 +08:00

259 lines
7.9 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NAS(群晖\+飞牛)MoviePilot/TMM TMDB刮削 终极稳定技术方案
## 一、问题背景与核心故障根源
### 1\.1 设备环境差异
- **群晖NAS**:Mihomo代理正常、Hysteria2节点正常、UDP链路通畅、全局代理生效,MoviePilot/TMM刮削全部正常。
- **飞牛fnOS**:无系统全局代理、OVS虚拟交换机拦截UDP、Hysteria2(QUIC/UDP)链路大面积失效,导致所有TMDB API请求超时/握手失败,媒体刮削完全不可用。
### 1\.2 核心技术故障定论
本次故障**不是节点、密钥、TLS版本、DNS污染问题**,是环境硬限制:
- TMDB CloudFront 强制仅支持 **TLS1\.3**;
- 传统TCP隧道(Vmess/Vless/AnyTLS/Mieru)存在内层TLS1\.3报文损坏缺陷;
- 唯一稳定的Hysteria2(QUIC/UDP)协议,被飞牛fnOS OVS/路由器UDP拦截;
- 飞牛Docker容器**不会自动继承宿主机代理**,裸网访问TMDB必然失败。
**结论**:飞牛无法本地稳定运行HY2代理,放弃飞牛本地代理,采用「双方案冗余架构」解决刮削问题。
## 二、整体架构设计(双冗余方案)
**主方案(长期日常使用)**:飞牛容器复用群晖Mihomo代理(全接口覆盖)
**备方案(断代理兜底)**:Cloudflare Worker带鉴权\+缓存TMDB中转(无需任何代理、纯裸网可用)
两套方案可随时切换,彻底解决飞牛TMDB刮削不稳定问题。
## 三、主方案:飞牛复用群晖Mihomo代理(推荐默认启用)
### 3\.1 前置必备条件(必须配置)
群晖Mihomo **config\.yaml** 核心配置(允许局域网访问):
```yaml
mixed-port: 7890
allow-lan: true
listen-address: 0.0.0.0
ipv6: false
```
群晖防火墙放行 **7890端口**,飞牛与群晖处于同一局域网、无跨VLAN隔离。
### 3\.2 MoviePilot 完整部署配置
飞牛docker\-compose\.yml,直接复用群晖SOCKS5代理,自动解决TMDB/Github/豆瓣全部外网请求。
```yaml
version: "3.8"
services:
moviepilot:
image: jxxghp/moviepilot:latest
container_name: moviepilot
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- /volume1/moviepilot:/app/config
environment:
- TZ=Asia/Shanghai
# 核心代理配置:远端解析域名,规避DNS污染
- PROXY_HOST=socks5h://192.168.1.100:7890
# Github加速,解决插件/资源下载失败
- GITHUB_PROXY=https://mirror.ghproxy.com/
network_mode: bridge
```
⚠️ 替换:`192.168.1.100` 为你的**群晖真实内网IP**,目录按需修改。
### 3\.3 MoviePilot 网页端配置
- 无需修改TMDB接口地址,保持官方默认
- PROXY\_HOST已由环境变量注入,无需重复填写
- 正常填写TMDB API Key即可
### 3\.4 TinyMediaManager\(TMM\) 部署配置
```yaml
version: "3.8"
services:
tinymediamanager:
image: tinymediamanager/tinymediamanager:latest
container_name: tinymediamanager
restart: unless-stopped
ports:
- "4000:4000"
volumes:
- /volume1/tmm:/config
environment:
- TZ=Asia/Shanghai
- ALL_PROXY=socks5h://192.168.1.100:7890
- NO_PROXY=127.0.0.1,localhost,192.168.0.0/16
network_mode: bridge
```
### 3\.5 TMM 网页端代理配置(优先推荐)
- Proxy type: SOCKS5
- Host: 群晖内网IP
- Port: 7890
- 开启:Resolve hostnames remotely(远端域名解析,等价socks5h)
### 3\.6 连通性验证命令(飞牛SSH执行)
```bash
docker exec -it moviepilot curl -v --socks5-hostname 192.168.1.100:7890 https://api.themoviedb.org/3/movie/550?api_key=你的TMDB密钥
```
返回JSON即为代理通路正常。
## 四、备方案:CF Worker 鉴权\+缓存 TMDB 中转(无代理兜底)
**适用场景**:群晖关机、代理节点故障、飞牛UDP彻底不通,**零代理依赖**完成TMDB刮削。
**核心优势**:TCP链路传输、不受UDP/OVS限制、带密码防盗刷、自带缓存提速、节省TMDB/CF额度。
### 4\.1 主中转Worker代码(鉴权\+缓存)
新建Worker,清空默认代码,粘贴如下完整版:
```javascript
export default {
async fetch(request, env) {
// 自定义你的访问密钥
const ACCESS_SECRET = "自定义随机密钥";
// 缓存有效期1小时,可改为600(10分钟)/86400(24小时)
const CACHE_TTL = 3600;
const auth = request.headers.get("X-Tmdb-Secret");
if (!auth || auth !== ACCESS_SECRET) {
return new Response("Access Denied", { status: 403 });
}
const targetHost = "api.themoviedb.org";
const url = new URL(request.url);
url.hostname = targetHost;
const newReq = new Request(url, request);
newReq.headers.set("Host", targetHost);
// GET请求缓存加速
if (request.method === "GET") {
const cacheKey = new Request(newReq.url, newReq);
const cache = caches.default;
let response = await cache.match(cacheKey);
if (!response) {
response = await fetch(newReq);
response = new Response(response.body, response);
response.headers.set("Cache-Control", `s-maxage=${CACHE_TTL}`);
await cache.put(cacheKey, response.clone());
}
return response;
}
return await fetch(newReq);
}
}
```
### 4\.2 缓存清理方案(三种方式)
#### 方式1:临时绕过缓存(单影片刷新,最简单)
链接后追加参数:`&_nocache=随机数字`
#### 方式2:全局一键清缓存(批量重刷库)
修改任意一行Worker代码并重新部署,CF边缘节点缓存**全部自动清空**。
#### 方式3:精准单条缓存删除(进阶)
单独部署purge清理Worker,支持指定路径删除缓存(文档末尾附代码)。
### 4\.3 MoviePilot 切换Worker配置
- 清空 **PROXY\_HOST**(关闭代理)
- TMDB API地址:`https://你的worker域名.workers.dev/3`
- 自定义请求头新增:`X-Tmdb-Secret: 你的自定义密钥`
- 保留原有TMDB Key
### 4\.4 TMM 切换Worker配置
- TMDB API URL 替换为Worker地址
- Custom HTTP Headers 添加 `X-Tmdb-Secret: 你的密钥`
- 关闭软件内代理设置
### 4\.5 缓存清理Purge Worker代码(精准删除单条缓存)
```javascript
export default {
async fetch(request, env) {
const ACCESS_SECRET = "和主Worker一致的密钥";
const auth = request.headers.get("X-Tmdb-Secret");
if (!auth || auth !== ACCESS_SECRET) {
return new Response("Access Denied", { status: 403 });
}
const url = new URL(request.url);
const targetPath = url.searchParams.get("path");
if (!targetPath) {
return new Response("Missing ?path=/3/movie/550", { status: 400 });
}
const cacheUrl = new URL(`https://你的主worker域名.workers.dev${targetPath}`);
const cacheReq = new Request(cacheUrl);
const cache = caches.default;
await cache.delete(cacheReq);
return new Response(`Purged: ${cacheUrl.toString()}`);
}
}
```
## 五、两套方案取舍标准
|方案|适用场景|优点|缺点|
|---|---|---|---|
|群晖代理复用(主)|日常长期使用、群晖开机|全覆盖(TMDB/Github/豆瓣)、无额度限制、速度稳定|依赖群晖在线|
|CF Worker中转(备)|群晖关机、代理故障、UDP拦截|零代理依赖、抗网络污染、自带缓存加速|仅覆盖TMDB、有每日免费额度|
## 六、通用排坑清单(飞牛专属)
1. **禁止使用127\.0\.0\.1**:容器内回环地址指向自身,必须填写群晖内网IP
2. **必须开启allow\-lan: true**:群晖Mihomo禁止仅监听127\.0\.0\.1
3. **飞牛关闭IPv6**:规避隧道TLS1\.3握手异常
4. **放弃飞牛本地HY2**:fnOS OVS\+路由器UDP拦截为硬故障,无法修复
5. **优先软件内置代理**:MoviePilot/TMM原生代理优于系统环境变量代理
## 七、最终落地规范
- 日常默认:**群晖Mihomo代理复用方案**
- 故障兜底:**CF Worker鉴权缓存中转方案**
- 永久废弃:飞牛本地Hysteria2代理、TCP隧道(AnyTLS/Mieru/Vmess)
> (注:部分内容可能由 AI 生成)