Recipya v1.2.2 配置参数详解
Recipya v1.2.2(Go 版)配置三通道全解:config.json 11 字段与 RECIPYA_* 11 变量分类表、文件吃掉环境变量的优先级源码、Docker 下 UI 改配置只进进程不持久化的陷阱、bypassGuide 改参→重启→验证实测闭环、生产安全基线与反代 /ws 要点。
Recipya v1.2.2 配置参数详解
目标:给出 Recipya v1.2.2(Go 版,reaper47/recipya)两条配置通道——卷内
config.json与RECIPYA_*环境变量——的全量参数分类、优先级规则源码级解读、UI 设置页与配置文件的分界,以及"改参→重启→验证"的实测闭环。全部参数语义以 v1.2.2 tag 源码(internal/app/app.go)与官方文档站实查为准,实测环境为/opt/data/quzuo/tmp/recipya/的 8163 端口容器。
一、配置体系总览:三条通道,两种命运
Recipya 的配置面比看起来小,但通道之间的优先级和持久化行为差异是最大陷阱:
| 通道 | 位置 | 何时生效 | 持久性 |
|---|---|---|---|
config.json | 卷内 /root/.config/Recipya/config.json | 存在即完全接管(环境变量被忽略) | 持久(文件) |
RECIPYA_* 环境变量 | compose environment: | 仅当 config.json 不存在时读取 | 持久(compose 文件) |
| UI 设置页(管理员) | PUT /settings/config | 立即(进程内) | ⚠️ Docker 下不持久(见 §五) |
优先级规则源码(internal/app/app.go 的 NewConfig(),v1.2.2 实查):
f, err := os.Open(filepath.Join(baseDir, "config.json"))
if err != nil {
NewConfig(nil) // 无文件 → 从 RECIPYA_* 环境变量构建 Config
} else {
NewConfig(f) // 有文件 → json.Decode,环境变量一概不读
}
推论:一旦你在卷里放了 config.json,compose 里的 RECIPYA_SERVER_* 全部变成摆设——排障时"改了 env 没反应"多半是这个原因。反之删掉 config.json,环境变量立即恢复话语权。
二、config.json 全量参数(文件模式)
官方样例 deploy/config.example.json(v1.2.2 tag 实查),结构与源码 ConfigFile 一一对应:
{
"email": {
"from": "my@email.com",
"sendGridAPIKey": "API_KEY"
},
"integrations": {
"azureDocumentIntelligence": {
"endpoint": "https://{resource_name}.cognitiveservices.azure.com/",
"key": "KEY_1"
}
},
"server": {
"autologin": false,
"bypassGuide": false,
"isDemo": false,
"isProduction": false,
"noSignups": false,
"port": 8078,
"url": "http://0.0.0.0"
}
}
2.1 server 组(服务端行为)
| 字段 | 类型/默认 | 语义与实测注记 |
|---|---|---|
server.port | int,必填 | 应用监听端口(0.0.0.0:<port>);Docker 内保持 8078 以匹配官方 compose 映射。改它必须同步改 ports: 映射 |
server.url | http://0.0.0.0 | 对外基地址,用于邮件内链接与 Address() 组装;公网部署填 https://recipya.example.com |
server.autologin | false | 免登录模式:启动时 InitAutologin() 直接以单用户进入,适合"家里 NAS 只给自己用";设 true 后注册/登录页不再必要 |
server.bypassGuide | false | 跳过内置使用向导(/guide/en 拦截页)。实测:false→true 后匿名 GET / 由 303 /guide/en 变为 303 /auth/login(§四闭环) |
server.isDemo | false | 演示模式:禁用设置保存(源码 Update() 首行 return errors.New("demo disabled"))、UI 展示演示横幅 |
server.isProduction | false | 生产标志:配合 https URL 时 cookie 加 Secure(IsCookieSecure());且 Address() 直接采用 url 不拼端口 |
server.noSignups | false | 关闭注册:/auth/register 路由被中间件重定向。建好账号后强烈建议 true,否则公网实例任何人可注册 |
2.2 email 组(SendGrid 集成)
| 字段 | 默认 | 语义 |
|---|---|---|
email.from | "" | SendGrid 发信地址(注册确认、忘记密码两类邮件) |
email.sendGridAPIKey | "" | SendGrid API key(免费层 100 封/日够用) |
留空即关闭邮件:注册确认邮件只入队不发送,不阻塞登录(实测);忘记密码功能不可用。
2.3 integrations 组(Azure 文档智能 OCR)
| 字段 | 默认 | 语义 |
|---|---|---|
integrations.azureDocumentIntelligence.key | "" | Azure DI 资源 KEY 1 |
integrations.azureDocumentIntelligence.endpoint | "" | 资源 Endpoint(仅 East US/West US2/West Europe 可用) |
用于"纸质食谱扫描数字化"(POST /recipes/add/ocr)。两项任一为空时 OCR 入口返回 toast Feature Disabled(源码实测)。免费层 F0:500 次/月、单文档 4MB、PDF 仅前两页。
三、RECIPYA_* 环境变量全量(env 模式)
与 config.json 字段一一映射(源码 NewConfig(nil) 分支),仅当卷内无 config.json 时生效:
| 变量 | 对应字段 | 默认 | 备注 |
|---|---|---|---|
RECIPYA_SERVER_PORT | server.port | (无,必填) | strconv.ParseInt 解析,非法值静默变 0 |
RECIPYA_SERVER_URL | server.url | ""→兜底 http://0.0.0.0 | |
RECIPYA_SERVER_AUTOLOGIN | server.autologin | false | 字符串 =="true" 才为真 |
RECIPYA_SERVER_BYPASS_GUIDE | server.bypassGuide | false | 同上 |
RECIPYA_SERVER_IS_DEMO | server.isDemo | false | |
RECIPYA_SERVER_IS_PROD | server.isProduction | false | |
RECIPYA_SERVER_NO_SIGNUPS | server.noSignups | false | |
RECIPYA_EMAIL | email.from | "" | |
RECIPYA_EMAIL_SENDGRID | email.sendGridAPIKey | "" | |
RECIPYA_DI_KEY | integrations...key | "" | 旧名 RECIPYA_VISION_KEY 已废弃(启动打印弃用提示) |
RECIPYA_DI_ENDPOINT | integrations...endpoint | "" | 尾部 / 自动 Trim |
布尔变量注意:compose 里写 true/"true" 等价,但写 1/yes 不生效(源码只认字符串 "true")。
四、改参→重启→验证闭环(实测)
以 bypassGuide 为例,演示文件模式的标准改参流程:
4.1 改参前基线
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://127.0.0.1:8163/
# 303 http://127.0.0.1:8163/guide/en ← 匿名被向导拦截
4.2 写入 config.json(改 bypassGuide=true)
docker exec recipya-1.2.2-evidence sh -c 'cat > /root/.config/Recipya/config.json <<EOF
{
"email": {"from": "", "sendGridAPIKey": ""},
"integrations": {"azureDocumentIntelligence": {"endpoint": "", "key": ""}},
"server": {"autologin": false, "bypassGuide": true, "isDemo": false, "isProduction": false, "noSignups": false, "port": 8078, "url": "http://0.0.0.0"}
}
EOF'
4.3 重启并验证
docker restart recipya-1.2.2-evidence
docker logs --tail 3 recipya-1.2.2-evidence
# goose: no migrations to run. current version: 20241219030306
# Serving HTTP server at address http://0.0.0.0:8078
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://127.0.0.1:8163/
# 303 http://127.0.0.1:8163/auth/login ← 向导已跳过,bypassGuide 生效
同时验证了优先级规则:容器 env 里 RECIPYA_SERVER_BYPASS_GUIDE=false 仍在,但 config.json 接管后其值被忽略。
改参副作用(实测):docker restart 后内存 session 清空,旧 cookie 访问 /recipes 返回 303 跳登录,需重新登录。改参窗口期会踢掉所有在线用户。
4.4 JSON 校验陷阱
NewConfig 解码失败直接 os.Exit(1)("The configuration file must be present.")——config.json 写坏一个逗号容器就 CrashLoop。改完先校验:
docker exec recipya-1.2.2-evidence sh -c 'cat /root/.config/Recipya/config.json | python3 -c "import json,sys; json.load(sys.stdin); print(\"OK\")" 2>/dev/null || echo 无python则用 jq'
(实测镜像为 alpine 无 python3/jq,可在宿主校验后再拷入。)
五、UI 设置页 vs 配置文件:哪些参数"改得住哪"
管理员 UI(Settings→Server 等)通过 PUT /settings/config 写配置,表单字段与 config.json 的映射(源码 settingsConfigPutHandler 实查):
| UI 表单字段 | config 字段 |
|---|---|
server.autologin(开关) | server.autologin |
server.bypassGuide | server.bypassGuide |
server.noSignups | server.noSignups |
server.production | server.isProduction |
integrations.ocr.key / integrations.ocr.url | Azure DI key/endpoint |
email.from / email.apikey | SendGrid 两项 |
⚠️ Docker 模式持久化陷阱(源码级实测结论):ConfigFile.Update() 在非 Docker 环境把变更 marshal 回写 config.json;但在容器内(isRunningInDocker() 判 /proc/1/cgroup 或 /.dockerenv)只执行一串 os.Setenv(...)——变更仅存活于当前进程,docker compose up -d 重建容器后全部回退到 compose/env 初始值。
运维守则:Docker 部署以 config.json 为唯一事实来源;UI 里改完 server 类开关,必须同步落到卷内 config.json(或 compose env),否则重启即丢。
不属于本通道的用户级设置(度量衡 imperial/metric、自动换算、营养显示、主题、搜索偏好等)存 SQLite user_settings 表,随数据库备份走,不在配置文件里。
六、生产部署推荐配置
公网/家庭网关暴露场景的最小安全基线:
{
"email": {"from": "noreply@example.com", "sendGridAPIKey": "<SG key>"},
"integrations": {"azureDocumentIntelligence": {"endpoint": "", "key": ""}},
"server": {
"autologin": false,
"bypassGuide": true,
"isDemo": false,
"isProduction": true,
"noSignups": true,
"port": 8078,
"url": "https://recipya.example.com"
}
}
配套动作:
- 先注册首个账号(即 admin),再设
noSignups=true重启。 isProduction=true+ https URL → 会话 cookie 带 Secure(源码IsCookieSecure()条件)。- 反代(Caddy/Traefik/Nginx)转发到宿主 8163 映射口;
/ws路径必须允许 WebSocket Upgrade(HTMX 导入/导出功能依赖它,反代默认配置常丢 Upgrade 头)。 - 忘记密码/注册确认邮件需要 SendGrid 两项配齐才可用。
- 卷
/root/.config/Recipya纳入备份计划(见 CLI 篇)。
七、参数速查与常见改参场景
| 场景 | 改哪里 | 生效方式 |
|---|---|---|
| 换宿主端口 | compose ports:(容器内 8078 别动) | docker compose up -d |
| 跳过向导 | server.bypassGuide=true 或 RECIPYA_SERVER_BYPASS_GUIDE=true | restart(§四实测) |
| 单用户免登录 | server.autologin=true | restart;启动日志 Could not initialize the autologin feature 表示库中无用户 |
| 关闭注册 | server.noSignups=true | restart |
| 启用 OCR | Azure DI key+endpoint(config.json 或 RECIPYA_DI_*) | restart;Settings 页可测连接 |
| 启用邮件 | SendGrid from+key | restart |
| 公网 https | isProduction=true + url=https://... | restart + 反代 Upgrade |
| 重置管理员配置 | 删除卷内 config.json | restart 后回退 env 模式 |
八、小结
Recipya v1.2.2 的配置面就一个 config.json(7 个 server 字段 + 2 个 email + 2 个 integrations)与 11 个 RECIPYA_* 环境变量,但三条通道的**优先级(文件吃掉 env)与持久性(Docker 下 UI 改动只进进程环境)**才是真正的坑位。把 config.json 当作唯一事实来源、改参走"写文件→restart→HTTP 断言"闭环、反代放行 /ws,Recipya 的配置管理就只剩"小"这一个字。备份恢复与命令行工具链见 《Recipya v1.2.2 常用 CLI 命令与工具详解》。