YumCut v0.1.0 配置参数详解

YumCut v0.1.0 四进程配置参数逐项详解:主应用 example.env 分组说明、存储服务 8 项、daemon 全参数表,含共享口令 403/200、CORS 白名单放行/拦截、轮询间隔与调度观测三组改配置实测。

YumCutYumCutNode.jsMySQL2026/10/25

YumCut v0.1.0 配置参数详解

目标:逐项讲清 YumCut v0.1.0 自托管四件套(主应用 app、MySQL、存储服务 storage、渲染守护 daemon)的全部关键配置参数——归属文件、含义、默认值、取值约束与修改后的生效方式,并对代表性参数做「改配置 → 看回显」的实测验证。文中参数以仓库随附的三个官方模板(example.env、storage/env.example、daemon.env.example,快照 6401fe6/c89c35f,取材日期 2026-10-25)为准,实测环境为 Docker Compose 编排的四服务部署(编排与部署全过程见《YumCut v0.1.0 Docker Compose 部署指南》)。

一、配置体系总览

YumCut 没有统一的配置文件,配置全部走环境变量,按进程拆成三组,互不通用:

进程配置载体(部署篇实测形态)官方模板生效方式
主应用 app编排 env_file: ./.env.app + build.args仓库根目录 example.env普通参数改后 docker compose up -d 重建即生效;NEXT_PUBLIC_* 与 NEXTAUTH_URL 编译进前端,必须重新 build
存储服务 storage编排 environment: 直注仓库根目录 env.example改后 docker compose up -d 生效
渲染守护 daemon编排 env_file: ./.env.daemon(另挂载为 /app/.daemon.env)仓库根目录 daemon.env.example改后 docker compose up -d daemon 生效

三条全局规则:

  1. 构建期与运行期分离:NEXT_PUBLIC_STORAGE_BASE_URL、NEXTAUTH_URL 在 Next.js 生产构建时被固化进前端产物,运行期改环境变量无效;其余参数都是运行期读取。
  2. 三处共享口令必须一致:DAEMON_API_PASSWORD 同时出现在主应用、存储服务、daemon 三处配置中,任何一处不一致,daemon 的请求会被对端以 403 拒绝(实测对照见 5.1)。
  3. 密钥类参数支持「内容或路径」两种写法:UPLOAD_SIGNING_PRIVATE_KEY/UPLOAD_SIGNING_PUBLIC_KEY 既可以粘贴 PEM 全文,也可以写文件路径,本文编排按路径挂载到 /run/secrets/。

💡 技术拓展:「环境变量注入配置」只是十二要素应用的一种形态。常见配置方案对比——

方案特点适用场景
环境变量/env 文件无侵入、与编排天然契合容器化部署,YumCut 所用
配置文件(YAML/JSON)结构清晰、可版本化参数层级深的单体应用
配置中心(Apollo/Nacos)动态下发、热更新多实例微服务集群

YumCut 全量走环境变量,改配置即改编排再重建,没有热更新能力。

二、主应用参数详解

主应用的完整参数模板是仓库根目录的 example.env。按用途分组逐项说明,加粗项为最小可用部署的必填项。

2.1 数据库与调度

参数含义默认/示例说明
DATABASE_URLMySQL 连接串mysql://user:password@localhost:3306/yumcut库须为 utf8mb4;编排内写服务名 mysql。缺失时 Prisma 迁移与启动直接失败
ENABLE_PUBLISH_SCHEDULER定时发布总开关00=对所有人关闭(白名单除外),1=全局开启
PUBLISH_SCHEDULER_BETA_USERS调度器灰度名单空逗号分隔的用户 ID 列表,总开关为 0 时仅这些用户可见

2.2 上传签名密钥对与存储地址

参数含义说明
UPLOAD_SIGNING_PRIVATE_KEYRSA 私钥(PEM 内容或路径)主应用用它给浏览器签发上传/删除授权;生成方法见部署篇 4.2
UPLOAD_SIGNING_PUBLIC_KEYRSA 公钥(PEM 内容或路径)主应用与存储服务各持一份用于验签
NEXT_PUBLIC_STORAGE_BASE_URL浏览器直连存储服务的地址构建期固化;必须是用户浏览器可达的地址,填编排内网地址会导致上传失败(部署篇 Q4)
TEST_STORAGE_BASE_URL自动化测试用的存储地址仅测试场景使用
STORAGE_PUBLIC_URL存储服务对外拼接媒体链接的 base与存储服务侧同名参数对应

2.3 会话与登录

参数含义说明
NEXTAUTH_URL站点对外地址生产构建强制校验,缺失直接构建失败(部署篇 Q1)
NEXTAUTH_SECRET会话 JWT 签名密钥openssl rand -hex 32 生成;轮换后全部旧会话失效
ALLOW_NO_OAUTH逃生门:无 OAuth 时允许构建自用部署设 1;此时界面无注册入口,账号开通走数据库(部署篇 5.3)
ALLOW_NO_REVIEW_AUTH逃生门:跳过审核账号构建校验缺 REVIEW_LOGIN_EMAIL/PASSWORD 时构建必须(部署篇 Q2)
GOOGLE_CLIENT_ID/SECRET 等Google OAuth可选,配置后界面出现 Google 登录
APPLE_* 系列Sign in with Apple可选,含团队 ID、私钥、IAP 共享密钥等
MOBILE_JWT_SECRET 等移动端会话仅移动 App 接入需要

2.4 共享口令

参数含义说明
SERVICE_API_PASSWORD服务级接口口令保护 /api/cron/planned-emails 等端点,调用方带 x-service-password 头
DAEMON_API_PASSWORDdaemon 专用口令daemon 调主应用 /api/daemon/* 与存储服务健康接口时带 x-daemon-password 头;实测 403/200 对照见 5.1

2.5 可选业务参数(按模板分组速查)

以下参数在最小可用部署中全部留空即可,列全以便按需启用:

  • 邮件:EMAIL_SEND_PROVIDER(postal/resend 二选一)、POSTAL_API_URL/API_KEY/FROM_EMAIL/WEBHOOK_PUBLIC_KEY、RESEND_API_KEY/FROM_EMAIL/WEBHOOK_SECRET 等。
  • Stripe 计费:STRIPE_SECRET_KEY、STRIPE_WEBHOOK_SECRET、STRIPE_WEEKLY_PRICE_ID($2.99/75 代币)、STRIPE_MONTHLY_PRICE_ID($19.99/750 代币)、STRIPE_MONTHLY_PRO_PRICE_ID($34.99/1500 代币)及两个 legacy 档位;自用可整组留空。
  • YouTube 发布:YOUTUBE_CLIENT_ID/SECRET、PUBLISH_CHANNEL_TOKEN_SECRET(32 位以上随机串,加密发布频道 token)。
  • AI 增强:RUNWARE_IMAGE_EDITOR_API_KEY(图生图)、VOICE_CLONE_RUNPOD_API_KEY/VOICE_CLONE_RUNPOD_ENDPOINT_ID(声音克隆,模板默认端点 ine3ps1u7rkduw)。
  • Telegram:TELEGRAM_BOT_TOKEN/USERNAME/WEBHOOK_SECRET,用于账号绑定与通知。
  • 界面开关:NEXT_PUBLIC_ENABLE_AUDIO_TONE_PROMPT(0 隐藏 / 1 显示「音色提示」控件,构建期固化)。

三、存储服务参数详解

存储服务的完整模板只有 8 个参数(env.example),逐项说明:

参数含义默认/示例实测要点
MEDIA_ROOT媒体文件落盘根目录./media编排中固定为卷挂载点 /data/media
STORAGE_PUBLIC_URL拼公开媒体链接的 basehttp://localhost:4001必须是外部可达地址,否则生成的链接用户打不开
STORAGE_ALLOWED_ORIGINS允许调用上传/删除接口(POST/OPTIONS)的浏览器来源逗号分隔列表只放行主应用来源;实测对照见 5.2
MEDIA_CORS_ALLOWLIST允许拉取 /api/media 的浏览器来源同上,支持 *与上一项独立,媒体读取可单独放宽
MEDIA_REQUIRE_SIGNED_DOWNLOAD是否要求媒体下载 URL 带签名false默认关闭;开启后未签名下载被拒
UPLOAD_SIGNING_PUBLIC_KEY验签公钥(PEM 路径)./keys/upload_public.pem必须与主应用持有的密钥对匹配
DAEMON_API_PASSWORDdaemon 访问存储的共享口令changeme与主应用、daemon 三处一致
PORT监听端口4001本文编排固定 3333 并映射到宿主 8129

四、daemon 参数详解

daemon 的完整模板是 daemon.env.example,按功能分组:

4.1 身份与上游地址

参数含义说明
DAEMON_ID实例唯一标识用于监控与任务锁,多实例时各取值必须不同且稳定
DAEMON_API_BASE_URL主应用地址(含协议)编排内网 http://app:3000
DAEMON_STORAGE_BASE_URL存储服务地址编排内网 http://storage:3333
DAEMON_STORAGE_HEALTH_PATH存储健康检查路径默认 /api/storage/health
DAEMON_HEALTH_PATH主应用侧健康检查路径默认 /api/daemon/health,启动自检用
DAEMON_API_PASSWORD共享口令见全局规则 2

4.2 轮询与并发

参数含义默认实测要点
DAEMON_INTERVAL_MS调度 tick 间隔(毫秒)1000改大降低数据库轮询压力;改值实测见 5.3
DAEMON_MAX_CONCURRENCY单实例并行任务数2tick 快照中的 capacity 字段即此值
DAEMON_VERBOSE_SCHEDULER调度器观测开关关设 1 后每个 tick 输出快照日志(5.3 实测)
DAEMON_TASK_TIMEOUT_SECONDS单任务看门狗超时(秒)3600超时任务被判定卡死并回收
DAEMON_REQUEST_TIMEOUT_MSdaemon→主应用 HTTP 超时(毫秒)15000网络抖动大时适当调大

4.3 渲染工作区与脚本

参数含义说明
DAEMON_SCRIPT_WORKSPACEv1 脚本工作区绝对路径指向私有仓库 video-slides/ai-agent
DAEMON_SCRIPT_WORKSPACE_V2v2 短视频脚本工作区指向私有仓库 yumcut-shorts-tools
DAEMON_CHARACTERS_WORKSPACE角色(lipsync)工作区指向 yumcut-characters
DAEMON_SCRIPT_CAPTION字幕渲染工作区提供 render:python/render:headless 两个脚本
DAEMON_PROJECTS_WORKSPACE项目产物根目录脚本、音频、日志落盘处
DAEMON_SCRIPT_MODE脚本执行模式fast(--fast)或 normal(旧行为)
DAEMON_CAPTIONS_RENDERER字幕渲染器缺省为 Python 渲染器;设 legacy 回退 Node 渲染器
DAEMON_AUDIO_DEFAULT_VOICE默认配音音色Kore(Gemini 音色)
DAEMON_VOICE_CLONE_FALLBACK_DIR声音克隆兜底目录命中时优先走 RunPod 克隆生成
DAEMON_SKIP_FFMPEG_CHECK跳过 FFmpeg 版本自检逃生门;设置背景见部署篇 Q3

⚠️ 四个「脚本工作区」参数指向的仓库均为作者私有仓库(2026-10-25 实查 GitHub 返回 404),自托管用空目录占位即可让 daemon 正常启动与调度,但渲染任务无法真正执行——这是开源版的边界,不是配置错误。

五、配置修改与生效实测

5.1 共享口令:403/200 对照

DAEMON_API_PASSWORD 的生效验证:不带口令访问存储健康接口被拒,带正确口令放行:

curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://192.168.146.128:8129/api/storage/health
curl -s -H 'x-daemon-password: q1w2e3r4' http://192.168.146.128:8129/api/storage/health

实测回显:

HTTP 403
{"ok":true,"time":"2026-10-25T10:34:22.606Z"}

第一行 403 证明口令校验生效;第二行 ok:true 证明编排中存储服务侧的口令与请求携带值一致。

5.2 CORS 来源白名单:放行与拦截对照

STORAGE_ALLOWED_ORIGINS 只放行了主应用来源 http://192.168.146.128:8130。以浏览器预检(OPTIONS)验证,放行来源的响应带完整 CORS 头:

curl -s -D - -o /dev/null -X OPTIONS http://192.168.146.128:8129/api/storage/user-images \
  -H 'Origin: http://192.168.146.128:8130' -H 'Access-Control-Request-Method: POST' | grep -iE '^HTTP|access-control'

实测回显:

HTTP/1.1 204 No Content
access-control-allow-credentials: true
access-control-allow-headers: content-type
access-control-allow-methods: POST,OPTIONS
access-control-allow-origin: http://192.168.146.128:8130

换成未放行来源,同样返回 204 但不带任何 CORS 头,浏览器会拦截后续真实请求:

curl -s -D - -o /dev/null -X OPTIONS http://192.168.146.128:8129/api/storage/user-images \
  -H 'Origin: http://evil.example.com' -H 'Access-Control-Request-Method: POST' | grep -iE '^HTTP|access-control'

实测回显:

HTTP/1.1 204 No Content

这正是白名单的意义:服务端不报错,但浏览器因缺少 access-control-allow-origin 而拒绝把响应交给页面脚本。新增前端域名时,把该域名追加到 STORAGE_ALLOWED_ORIGINS 与 MEDIA_CORS_ALLOWLIST 两个逗号列表,docker compose up -d 后生效。

5.3 轮询间隔与调度观测:改值实测

把 .env.daemon 中 DAEMON_INTERVAL_MS 由 1000 改为 5000,并追加 DAEMON_VERBOSE_SCHEDULER=1,应用配置:

cd /opt/yumcut/stack
docker compose up -d daemon

实测回显:

 Container yumcut-0-1-0-stack-daemon-1 Started

观察日志,tick 快照按 5 秒一拍输出(时间戳 10:44:10 → 15 → 20 → 25),capacity 即为 DAEMON_MAX_CONCURRENCY=2:

docker compose logs daemon --since 3m | grep -A4 'Scheduler tick snapshot' | head -12

实测回显(输出节选,实测首尾):

daemon-1  | [2026-10-25T10:44:10.113Z] INFO  Scheduler tick snapshot {
daemon-1  |   "capacity": 2,
daemon-1  |   "eligibleCount": 0,
daemon-1  |   "inFlight": 0
daemon-1  | }
daemon-1  | [2026-10-25T10:44:15.117Z] INFO  Scheduler tick snapshot {
...
daemon-1  | [2026-10-25T10:44:25.120Z] INFO  Scheduler tick snapshot {

eligibleCount: 0 / inFlight: 0 表示当前队列没有可领取的任务。验证完毕把两项改回原值(1000、删除观测开关)再 up -d,日志即恢复安静——观测开关只适合排障时短期开启,常规运行会持续刷日志。

六、常见问题

Q1:改了 NEXT_PUBLIC_STORAGE_BASE_URL 或 NEXTAUTH_URL 并 up -d,前端行为没有变化

原因:这两个参数在 Next.js 生产构建时固化进前端产物,运行期改环境变量无效。必须 docker compose build app && docker compose up -d 重新构建。

Q2:daemon 日志反复 403 / Invalid daemon credentials

原因:三处 DAEMON_API_PASSWORD 不一致(主应用 .env.app、存储服务编排、.env.daemon)。改齐后重建,用 5.1 的 403/200 对照验证。

Q3:构建主应用时报 NEXTAUTH_URL is required 或 /api/mobile/auth/review 收集失败

这两项是构建期强制校验,分别用构建参数 NEXTAUTH_URL 与逃生门 ALLOW_NO_REVIEW_AUTH=1 解决,完整排障实录见《YumCut v0.1.0 Docker Compose 部署指南》第八章 Q1/Q2。

Q4:上传页面报 CORS 错,但服务端日志无异常

原因:来源不在 STORAGE_ALLOWED_ORIGINS 白名单时服务端返回 204 但不下发 CORS 头,错误只出现在浏览器控制台。按 5.2 的对照法确认来源是否放行。

Q5:想让多个 daemon 实例并行渲染

为每个实例准备独立的 .env.daemon,DAEMON_ID 各不相同;数据库锁保证同一任务不被重复领取,DAEMON_MAX_CONCURRENCY 控制单实例并发。多实例共享同一个 DAEMON_PROJECTS_WORKSPACE 时需要自行保证路径不冲突。

七、参考链接