Recipya v1.2.2 配置参数详解

Recipya v1.2.2(Go 版)配置三通道全解:config.json 11 字段与 RECIPYA_* 11 变量分类表、文件吃掉环境变量的优先级源码、Docker 下 UI 改配置只进进程不持久化的陷阱、bypassGuide 改参→重启→验证实测闭环、生产安全基线与反代 /ws 要点。

RecipyaRecipya食谱管理DockerSQLite2026/11/02

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.portint,必填应用监听端口(0.0.0.0:<port>);Docker 内保持 8078 以匹配官方 compose 映射。改它必须同步改 ports: 映射
server.urlhttp://0.0.0.0对外基地址,用于邮件内链接与 Address() 组装;公网部署填 https://recipya.example.com
server.autologinfalse免登录模式:启动时 InitAutologin() 直接以单用户进入,适合"家里 NAS 只给自己用";设 true 后注册/登录页不再必要
server.bypassGuidefalse跳过内置使用向导(/guide/en 拦截页)。实测:false→true 后匿名 GET / 由 303 /guide/en 变为 303 /auth/login(§四闭环)
server.isDemofalse演示模式:禁用设置保存(源码 Update() 首行 return errors.New("demo disabled"))、UI 展示演示横幅
server.isProductionfalse生产标志:配合 https URL 时 cookie 加 Secure(IsCookieSecure());且 Address() 直接采用 url 不拼端口
server.noSignupsfalse关闭注册:/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_PORTserver.port(无,必填)strconv.ParseInt 解析,非法值静默变 0
RECIPYA_SERVER_URLserver.url""→兜底 http://0.0.0.0
RECIPYA_SERVER_AUTOLOGINserver.autologinfalse字符串 =="true" 才为真
RECIPYA_SERVER_BYPASS_GUIDEserver.bypassGuidefalse同上
RECIPYA_SERVER_IS_DEMOserver.isDemofalse
RECIPYA_SERVER_IS_PRODserver.isProductionfalse
RECIPYA_SERVER_NO_SIGNUPSserver.noSignupsfalse
RECIPYA_EMAILemail.from""
RECIPYA_EMAIL_SENDGRIDemail.sendGridAPIKey""
RECIPYA_DI_KEYintegrations...key""旧名 RECIPYA_VISION_KEY 已废弃(启动打印弃用提示)
RECIPYA_DI_ENDPOINTintegrations...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.bypassGuideserver.bypassGuide
server.noSignupsserver.noSignups
server.productionserver.isProduction
integrations.ocr.key / integrations.ocr.urlAzure DI key/endpoint
email.from / email.apikeySendGrid 两项

⚠️ 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"
	}
}

配套动作:

  1. 先注册首个账号(即 admin),再设 noSignups=true 重启。
  2. isProduction=true + https URL → 会话 cookie 带 Secure(源码 IsCookieSecure() 条件)。
  3. 反代(Caddy/Traefik/Nginx)转发到宿主 8163 映射口;/ws 路径必须允许 WebSocket Upgrade(HTMX 导入/导出功能依赖它,反代默认配置常丢 Upgrade 头)。
  4. 忘记密码/注册确认邮件需要 SendGrid 两项配齐才可用。
  5. 卷 /root/.config/Recipya 纳入备份计划(见 CLI 篇)。

七、参数速查与常见改参场景

场景改哪里生效方式
换宿主端口compose ports:(容器内 8078 别动)docker compose up -d
跳过向导server.bypassGuide=true 或 RECIPYA_SERVER_BYPASS_GUIDE=truerestart(§四实测)
单用户免登录server.autologin=truerestart;启动日志 Could not initialize the autologin feature 表示库中无用户
关闭注册server.noSignups=truerestart
启用 OCRAzure DI key+endpoint(config.json 或 RECIPYA_DI_*)restart;Settings 页可测连接
启用邮件SendGrid from+keyrestart
公网 httpsisProduction=true + url=https://...restart + 反代 Upgrade
重置管理员配置删除卷内 config.jsonrestart 后回退 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 命令与工具详解》。

Recipya v1.2.2 配置参数详解 - Quzuo