RecipeSage 介绍与选型指南
RecipeSage v4.1.1 认知篇:julianpoy 自托管食谱管理器+协作购物清单的定位、Node24+tRPC+Prisma+PostgreSQL16+Valkey+Pushpin+Angular 架构纠偏(非 Ember/MongoDB)、六容器 ~616MiB 资源实测、注册/建谱/协作/导出 API 闭环回显、社区数据(988 stars/双许可)与 Mealie/Fork Recipes/ManageMeals 量化选型对比及 8 条纠偏(实测日期 2026-11-02)
RecipeSage 介绍与选型指南
定位一句话:RecipeSage 是 julianpoy 主导的自托管食谱管理器 + 协作购物清单(托管版 recipesage.com 同源代码),v4 线以 Node.js 24 + tRPC + Prisma + PostgreSQL 为后端、Angular 为前端、Pushpin 做实时同步,面向"抓取网页食谱入库、和家人/朋友共享购物清单与餐计划"的场景。本文基于 RecipeSage v4.1.1(2026-11-02 实测取证,Ubuntu 24.04.5 / Docker 六容器栈)给出功能面、架构、资源占用、社区状态与量化选型对比。部署实操见同专栏《RecipeSage Docker Compose 部署指南》,参数与 CLI 分别见《RecipeSage 4.1.1 配置参数详解》《RecipeSage 4.1.1 常用 CLI 命令与工具详解》。
一、环境信息
本文全部实测数据来自如下取证环境(2026-11-02):
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 24.04.5 LTS(x86_64) |
| Docker 引擎 | 29.9.2 |
| Docker Compose | v5.6.1 |
| 组件版本 | RecipeSage v4.1.1(api-v4.1.1 / static-v4.1.1 镜像) |
| 部署形态 | 官方 selfhost compose 六服务栈(proxy/static/api/pushpin/postgres/valkey) |
| 访问入口 | http://127.0.0.1:8162(宿主端口 8162) |
| 验收方式 | ⚠️ 本批次无浏览器自动化工具,页面验收降级为「HTTP 状态码 + <title> + REST API 全链路实测」 |
| 网络说明 | ⚠️ 实测环境直连 Docker Hub 受限,镜像经国内镜像加速源拉取成功;有直连条件的服务器按原 tag 拉取即可 |
二、软件概述
RecipeSage 由开发者 julianpoy 维护,采用"托管 SaaS(recipesage.com)+ 开源自托管"双轨模式:自托管版与托管版同源,官方为自托管用户单独维护部署仓库 julianpoy/RecipeSage-selfhost(提供权威 docker-compose.yml),文档站为 docs.recipesage.com(Docusaurus)。
纠偏①(仓库名):GitHub 仓库是 julianpoy/RecipeSage,不存在 RecipeSage/RecipeSage(实测 404)。
2.1 版本与社区数据(2026-11-02 实查 GitHub API)
| 维度 | 数据 |
|---|---|
| 最新稳定版 | v4.1.1(2026-10-31 发布);此前 v4.1.0(10-26)、v4.0.19(10-25) |
| stars / forks | 988 / 112 |
| open issues | 23 |
| 项目创建 / 最近推送 | 2019-01-07 / 2026-11-01 |
| 主语言 | TypeScript |
| 许可证 | 双许可:非商业用途 AGPL-3.0,商业用途需另行取得授权(GitHub license 字段因此显示 None) |
| 仓库结构 | monorepo:packages/{backend,cli,desktop,express,frontend,prisma,queue-worker,trpc,util} + webextension-v3(浏览器扩展)+ www,nx + pnpm 管理 |
版本节奏解读:三天两发的补丁节奏(10-25/10-26/10-31)说明 v4.1 线处于活跃维护期;但千级 star 的体量意味着社区规模明显小于 Mealie(见第七节对比),排障资料以官方 Discord 与 GitHub issues 为主。
2.2 技术栈(v4.1.1 实测)
纠偏②(重要):网络资料与旧文档常称 RecipeSage 为"Node/Ember + MongoDB"——那是 v3 及以前的形态。v4.1.1 实测技术栈:
| 层 | 实现 | 实测证据 |
|---|---|---|
| 运行时 | Node.js 24.22.2 | api 容器内 node --version |
| Web 框架 | Express 5.2.1 | package.json 依赖 |
| API 层 | tRPC 11.19.0 + trpc-to-openapi 3.3.3 | 生成 REST 兼容层 /compat/v2/* 与 openapi.json;实测 144 个 path、403KB |
| ORM | Prisma 7.10.1(69 个迁移) | 启动日志 69 migrations found in prisma/migrations |
| 数据库 | PostgreSQL 16(40 张业务表) | psql 实查;SequelizeMeta 表为旧版 Sequelize/MongoDB 迁移史遗留 |
| 队列/缓存 | Valkey(JOB_QUEUE_REDIS_HOST,BullMQ 风格 job) | compose 与 api 日志 Job queue has drained |
| 实时推送 | Pushpin(GRIP 协议,/grip/ws) | 独立 pushpin 容器 + nginx 路由 |
| 前端 | Angular(SPA,base href=/app/) | 3rdpartylicenses.txt 含 @angular/core/forms/router;chunk-*.js 为 esbuild 产物 |
💡 技术拓展:自托管应用的"实时同步"不止 Pushpin/GRIP 一种方案——
方案 特点 适用 原生 WebSocket 双向、需自管连接/重连/扇出 高频双向通信 SSE 单向服务端推送,走 HTTP 轻量通知 GRIP(Pushpin) 独立代理进程托管订阅/发布,应用只需向代理发 HTTP 指令 多实例共享连接、少改应用代码 RecipeSage 选择 Pushpin,是为了让协作购物清单/餐计划的多人实时编辑在自托管与云端多实例部署下由代理统一扇出。
三、核心架构
selfhost 形态为六服务 compose 栈,nginx 代理统一入口,路由实测(recipesage_proxy:/etc/nginx/conf.d/default.conf):
| 路径 | 去向 |
|---|---|
/ | 301 → /app/ |
/app/ | static(Angular 前端) |
/api/、/app/api/ | api:3000 |
/grip/ws | pushpin:7999/ws |
/minio/ | 可选 MinIO 存储(默认 filesystem 不启用) |
api 容器启动序列(scripts/selfhost-startup.sh):prisma migrate deploy(自动迁移)→ CLI seed → CLI indexRecipes(PostgreSQL 全文检索回填)→ 启动后端。持久化只有两卷:PG 数据 + apimedia 文件(FILESYSTEM_STORAGE_PATH=/rs-media)。
资源实测(docker stats --no-stream,空载 + 少量数据):
recipesage_proxy 6.754MiB / 15.57GiB 0.00%
recipesage_static 6.551MiB / 15.57GiB 0.00%
recipesage_api 516.7MiB / 15.57GiB 0.48%
recipesage_pushpin 35.09MiB / 15.57GiB 0.04%
recipesage_postgres 43.66MiB / 15.57GiB 3.27%
recipesage_valkey 7.27MiB / 15.57GiB 0.10%
合计约 616MiB,其中 api 占 84%(compose 显式 NODE_OPTIONS=--max-old-space-size=400 限堆)。镜像体积同样偏重:api-v4.1.1 解包 3.21GB(压缩 588MB)、static-v4.1.1 268MB——这是 RecipeSage 与单容器类食谱管理器最大的运维差异(见 7.1)。
四、功能特性(v4.1.1 实测面)
- 食谱库:手动录入 / URL 抓取 / 浏览器扩展抓取,标签(Labels/LabelGroups)、收藏、搜索(PostgreSQL FTS,CLI
indexRecipes回填)、"今天吃什么"随机推荐。 - 协作购物清单(一等公民):清单/条目/分类,
collaboratorUserIds多人协作,条目可关联来源食谱;实测 A 共享给 B 后 B 端立即可见。 - 好友体系:
createFriendship双向请求/接受,食谱可分享给好友。 - 餐计划(MealPlans):与购物清单同属协作对象。
- 导入/导出:导出 job 支持
txt|pdf|jsonld三种格式(实测 jsonld 产物为合法 schema.org Recipe);jobs 子路由内置 18 种外部服务导入适配器(copymethat、crouton、csv、enex、jsonld 等,见 openapi.json)。 - AI 能力(依赖外部 key):URL 抓取(clip)、OCR/PDF/文本解析、营养计算、助手对话——selfhost 默认不配
AI_API_KEY时相关端点不可用(实测 clip 返回 400)。 - 多端:Web、iOS/Android(Capacitor)、桌面(Electron,
packages/desktop)、浏览器扩展(webextension-v3)。 - API:tRPC 主接口 +
/compat/v2/*REST 兼容层(144 paths)+ openapi.json 自描述。
五、快速开始(最小可用示例)
以下四步在 2026-11-02 实测环境(端口 8162)逐条跑通,演示账号 admin@example.com / q1w2e3r4。完整部署过程见同专栏《RecipeSage Docker Compose 部署指南》。
5.1 注册(无需邮箱验证即可用)
curl -s -X POST http://127.0.0.1:8162/api/compat/v2/users/register \
-H 'Content-Type: application/json' \
-d '{"name":"admin","email":"admin@example.com","password":"q1w2e3r4"}'
实测回显(HTTP 200,token 为 96 位十六进制串):
{"token":"490d2318d743839953460fe010bc1a0ae5cfe8e2588bde69d74ac436ba1ccc71ef6a928226a9fe822cd4518b7814ccd7","userId":"42754089-a1d9-4e1d-8b04-7df237fbb337","email":"admin@example.com","isNewUser":true}
5.2 会话验证
curl -s http://127.0.0.1:8162/api/compat/v2/users/validateSession \
-H "Authorization: Bearer $TOKEN"
实测回显:"Valid"(HTTP 200)。
5.3 创建食谱
⚠️ 纠偏③:createRecipe 的 schema 要求 title/description/yield/activeTime/totalTime/source/url/notes/instructions/ingredients/rating/folder/labelIds/imageIds 全部字段出现(可空值也要给),folder 为枚举 main|inbox(传 null 报 invalid_value),时长用 ISO8601 格式(如 PT10M)。
curl -s -X POST http://127.0.0.1:8162/api/compat/v2/recipes/createRecipe \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"title":"Pasta Aglio e Olio","description":"Garlic chili pasta","yield":"2 servings",
"activeTime":"PT10M","totalTime":"PT15M","source":"quzuo G25","url":"","notes":"keep starchy water",
"instructions":"1. Boil pasta.\n2. Sauté garlic and chili in olive oil.",
"ingredients":"200 g spaghetti\n4 cloves garlic\n60 ml olive oil",
"rating":null,"folder":"main","labelIds":[],"imageIds":[]}'
实测回显:{"id":"fb231af7-5993-42d8-9bc8-e6a5862afaea"}(HTTP 200)。
5.4 查询食谱列表
⚠️ 纠偏④:getRecipes 是 POST(GET 返回 404),参数放 body:
curl -s -X POST http://127.0.0.1:8162/api/compat/v2/recipes/getRecipes \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"folder":"main","orderBy":"createdAt","orderDirection":"desc","offset":0,"limit":10}'
实测回显(HTTP 200):
{"recipes":[{"id":"fb231af7-5993-42d8-9bc8-e6a5862afaea","userId":"42754089-a1d9-4e1d-8b04-7df237fbb337","fromUserId":null,"title":"Pasta Aglio e Olio","description":"Garlic chili pasta","yield":"2 servings","activeTime":"PT10M","totalTime":"PT15M","source":"quzuo G25","url":"","folder":"main","createdAt":"2026-11-01T20:54:59.373Z","updatedAt":"2026-11-01T20:54:59.373Z","lastMadeAt":null,"rating":null,"recipeLabels":[],"recipeImages":[],"fromUser":null,"user":{"id":"42754089-a1d9-4e1d-8b04-7df237fbb337","name":"admin","handle":null,"enableProfile":false,"profileImages":[]}}],"totalCount":1}
统计接口同步验证:
curl -s http://127.0.0.1:8162/api/compat/v2/users/getMyStats -H "Authorization: Bearer $TOKEN"
实测回显:{"recipeCount":1,"recipeImageCount":0,"messageCount":0,"createdAt":"2026-11-01T20:54:43.926Z","lastLogin":null},闭环成立。
六、适用场景与限制
适合:
- 家庭/伴侣/朋友间共享购物清单与餐计划(协作是产品内核,不是附加功能);
- 从网页大量收藏食谱,且接受用浏览器扩展抓取(官方推荐路径,直接取当前页 HTML,绕开服务端抓取反爬);
- 需要 iOS/Android/桌面多端与同一实例同步。
限制/不适合:
- 商用受限:双许可,商业使用需向作者另行取得授权;
- AI 抓取依赖外部服务:不配
AI_API_KEY/SCRAPFLY_API_KEY时,服务端 URL clip 实测返回400 {"status":400};购物清单自动分类默认也走 RecipeSage 公有 API(GROCERY_CATEGORIZER_URL,本地替代需支持 AVX 的 ML 服务); - 栈最重:六容器 ~616MiB 常驻 + 3.21GB api 镜像,内存 <1GB 的小 VPS 吃紧;
- 社区规模:988 star,中文资料几乎为零,深度定制需读 TS 源码。
七、同类选型对比
7.1 与已实测自托管食谱管理器量化对比
| 维度 | RecipeSage v4.1.1 | Mealie v3.30.0(专栏 1367) | Fork Recipes(专栏 1345) | ManageMeals web v1.7.3/api v1.9.3(专栏 1366) |
|---|---|---|---|---|
| 技术栈 | Node24+tRPC+Prisma+Angular | Python/FastAPI+Vue | Python/Django(forkapi+fork.recipes 前后端分离) | Node/Next.js 全家桶(SvelteKit+Fastify) |
| 依赖组件 | PG16+Valkey+Pushpin+nginx(6 容器) | 单容器+可选 PG | 后端+PG+nginx | MongoDB+Valkey+Typesense 等(8 服务) |
| 常驻内存实测 | ~616MiB | 低(单容器) | 中 | 高 |
| 协作购物清单 | 原生一等公民(好友+collaborator) | 有清单,协作弱 | 弱 | 膳食计划强,清单协作一般 |
| 餐计划/膳食 | MealPlan 协作对象 | 有 | 无 | 核心卖点 |
| URL/AI 抓取 | 依赖外部 AI key 或浏览器扩展 | 本地 scraper 开箱可用 | OpenAI 抓取 | 抓取器独立服务 |
| 多端 | Web+iOS/Android+Electron+扩展 | Web+PWA | Web | Web |
| 许可证 | AGPL-3.0 非商业+商业另授 | AGPL-3.0 | MIT | AGPL-3.0 |
| 社区 | 988 stars | ~14k stars | 小 | 小 |
互链:Mealie 认知篇见 《Mealie 介绍与选型指南》;Fork Recipes 见 《Fork Recipes 介绍与选型指南》;ManageMeals 见 《ManageMeals 介绍与选型指南》。
7.2 选择建议
- 选 RecipeSage:核心诉求是"和家人朋友共同维护购物清单/餐计划"、需要官方移动与桌面客户端、接受为 AI 抓取配外部 key。
- 选 Mealie:只要个人/小家庭食谱库 + URL 抓取开箱即用,运维预算最小(单容器)。
- 选 ManageMeals:重"膳食计划"而非购物清单协作。
- 选 Fork Recipes:Django 技术栈偏好、需要 OpenAI 抓取管道。
- 不选 RecipeSage:商用产品内嵌(许可受限);1GB 以下小机器(栈重);纯离线无外部 AI 依赖且强依赖服务端 URL 抓取(clip 不可用)。
八、上手前必须知道的坑(本批次实测纠偏汇总)
- 仓库名是
julianpoy/RecipeSage,部署配置在julianpoy/RecipeSage-selfhost(compose 配置版本 2026-10-29)。 - 技术栈已换代:v4 是 PostgreSQL+Angular,不是 MongoDB+Ember;旧教程的 MongoDB 路径全部作废。
- 官方 compose 默认钉 v4.1.0,v4.1.1 tag 存在且实测可拉取(本批次已升级验证)。
- v4 已删除旧群组 API:
/api/groups实测 404;协作模型 = 好友(createFriendship)+ collaboratorUserIds。 - createRecipe 全字段必填 + folder 枚举 main|inbox(见 5.3);getRecipes 用 POST(见 5.4)。
- URL clip 无 AI key 即 400:selfhost 抓网页要么配
AI_API_KEY/SCRAPFLY_API_KEY,要么用浏览器扩展。 - 端口规划:本批次宿主用 8162(8161 已被其他组件占用);
API_PUBLIC_BASE_URL必须带/api后缀,改端口需同步改。 - 双许可:GitHub API 的 license 字段显示 None 正是因为非标准双许可,商用前先读 README 许可段。
九、小结
RecipeSage 是自托管食谱管理赛道里唯一把"协作购物清单 + 好友共享"做成产品内核的方案,多端客户端与 Pushpin 实时同步进一步贴合"家庭共同采购"场景;代价是 v4 换代后全家桶最重(六容器 ~616MiB)、AI 抓取依赖外部服务、且非商业双许可限制了商用。若你的场景是"两人以上共同维护食谱与采购清单",它是当前首选;单人轻量收藏则 Mealie 更省心。下一步实操请读《RecipeSage Docker Compose 部署指南》。
十、参考链接
- 源码仓库:https://github.com/julianpoy/RecipeSage
- 自托管部署仓库:https://github.com/julianpoy/RecipeSage-selfhost
- 官方文档:https://docs.recipesage.com (API 文档:https://docs.recipesage.com/api/)
- 托管版:https://recipesage.com
- 本实例 API 自描述:
http://<你的地址>/api/openapi.json(实测 403KB、144 paths)
取证说明:本文全部实测数据来自 2026-11-02 在 Ubuntu 24.04.5 / Docker 29.9.2 环境部署的 RecipeSage v4.1.1 六服务栈(REST API 注册/建谱/购物清单/好友协作/导出 job/CLI/备份全链路验证);浏览器工具不可用,页面验收降级为 HTTP+title+API 闭环;镜像经国内镜像源拉取。