
Tandoor Recipes 全解析自托管开源食谱管理、膳食规划与购物清单一体化的实践指南【免费下载链接】recipesApplication for managing recipes, planning meals, building shopping lists and much much more!项目地址: https://gitcode.com/GitHub_Trending/re/recipesTandoor Recipes本仓库项目名为 recipes是一款面向个人与家庭的食谱管理应用帮助你管理不断增长的数字化食谱收藏并在此基础上延伸出膳食计划、购物清单、菜谱书、分享协作与 AI 辅助等一系列能力。本文以仓库根目录的 README.md 为骨架结合 cookbook/models.py、docs/system/configuration.md、docs/install/docker.md 等源码与官方文档系统讲解该项目的定位、核心功能、技术架构、部署方式与关键配置读完你可以据此快速上手自建实例并理解其底层实现脉络。项目定位为永远增长的食谱收藏而生的自托管应用Tandoor Recipes 的官方描述是The recipe manager that allows you to manage your ever growing collection of digital recipes让你管理不断增长的数字化食谱收藏的食谱管理器。它是为收藏了大量食谱、希望与家人朋友共享或只是想让食谱井井有条的人群设计的见 README.md 的项目说明段落。需要特别注意的是其边界应用自带一套基础权限系统但官方明确说明它并不适合作为公开页面运行A basic permission system exists but this application is not meant to be run as a public page。这一点决定了它的典型使用场景是家庭局域网、自托管服务器或个人 VPS而不是面向公众的 SaaS 网站。从版本历史看该项目最初是为了对作者自己的数字化PDF食谱集合做索引、打标签和搜索而开发的随后逐步演进为功能全面的食谱管理系统见 docs/index.md 的 About 章节。核心功能全景README 将功能划分为三个层级核心功能、面向高阶用户的功能、必备特性。核心功能Core Features食谱管理使用快速直观的编辑器管理不断增长的食谱收藏膳食规划为每天规划多顿饭Meal Plan 功能对应数据模型 MealPlan购物清单可从膳食计划生成也可直接从食谱生成菜谱书将食谱按主题收集成书RecipeBook / RecipeBookEntry 模型见 cookbook/models.pyAI 辅助使用 AI 识别图片、整理食谱步骤、查找营养成分等分享协作与家人朋友分享食谱并协同维护Recipe 模型提供shared多对多字段与ShareLink分享链接机制。面向高阶用户的功能Made by and for power users强大的可定制搜索支持全文检索并基于 PostgreSQL 的 TrigramSimilarity 提供模糊匹配能力。代码侧证据非常直观Recipe模型上定义了两个SearchVectorFieldname_search_vector与desc_search_vector并在Meta中为它们建立了GinIndex见 cookbook/models.py#L1115-L1145搜索功能对应的实现位于 cookbook/helper/recipe_search.py并有配套的 test_recipe_search_text.py 等测试用例标签系统创建、搜索标签并支持将标签批量赋予所有匹配特定过滤条件的文件数据合并快速合并、重命名食材Ingredient、标签Keyword和单位Unit外部食谱导入从支持 ldjson 或 microdata分数或小数支持食材用量既可以显示为分数也可以显示为小数一键 Docker 部署附带 Kubernetes、Unraid、Synology 等部署示例主题定制可通过主题自定义界面外观静态主题文件位于 cookbook/static/themes/包含tandoor.min.css与tandoor_dark.min.css文件同步与 Dropbox、Nextcloud 同步食谱文件对应 cookbook/provider/ 目录下的 dropbox.py、nextcloud.py、local.py 等 Provider 实现。必备特性All the must haves移动端优化针对手机设备的使用体验做了专门优化前端基于 Vue 3 构建源码在 vue3/src/多语言本地化得益于社区贡献支持大量语言。仓库中 cookbook/locale/ 目录包含 30 余种语言的翻译如 de、fr、zh_CN、zh_Hant 等并有配套的编译脚本 scripts/make_compile_messages.py收藏迁移可从大量其他食谱管理软件导入收藏详见下文导入导出生态章节其他实用功能食谱缩放按份数自动调整用量、图片压缩、打印视图、超市管理Supermarket 模型等。技术架构与依赖栈从 requirements.txt 和仓库目录结构可以还原出项目的技术底座层级技术选型仓库证据Web 框架Django 5.2.16requirements.txtAPI 框架Django REST Framework 3.18.0 drf-spectacularOpenAPI 文档同上数据库PostgreSQLpg_trgm 扩展支持模糊搜索、可选 SQLite迁移文件 0003_enable_pgtrm.py、docs/system/configuration.md前端Vue 3 ViteTypeScriptvue3/、vue3/package.json认证django-allauth含 MFA 与社交登录、LDAPrequirements.txt、docs/features/authentication.md网页抓取recipe-scrapers、BeautifulSoup4、microdata、lxmlrequirements.txt存储本地文件、Dropbox、Nextcloud、S3 兼容对象存储cookbook/provider/、配置文档 S3 章节WSGI 服务器gunicorn容器内由 nginx 统一对外requirements.txt、docs/install/docker.md后端主应用位于cookbook/包内项目配置在 recipes/settings.py路由入口在 recipes/urls.py。数据模型集中在 cookbook/models.py共有 20 余个核心模型包括 Space空间多租户隔离、Recipe、MealPlan、ShoppingList、RecipeBook、Food、Ingredient、Unit、Automation自动化、ConnectorConfig外部连接器、ShareLink、CookLog、ViewLog 等模型类定义见 cookbook/models.py。数据库迁移文件从 0001 一直排到 0242反映了功能演进的完整历史例如0152_automation.py自动化功能、0215_connectorconfig.py外部连接器、0224_space_ai_credits_balance...AI 信用额度、0235_recipe_diameter...食谱直径字段、0236_household...家庭与库存位置等。源码视角核心 Recipe 模型解析以最关键的数据模型Recipe为例见 cookbook/models.py#L1086-L1147其核心字段包括name、description名称与描述servings、servings_text份数与份数文本支持按人数缩放的基础diameter、diameter_text模具直径数值与文本image、storage、file_uid、file_path图片与文件存储关联 Storage Provider支撑 Dropbox/Nextcloud 同步link、cors_link、source_url原始来源链接keywords、steps、properties关键词标签、步骤、自定义属性working_time、waiting_time准备时间与等待时间internal、private、shared内部/私有/分享协作标记nutrition营养成分关联 FDC 数据库可自动获取营养信息name_search_vector、desc_search_vectorGinIndex全文搜索向量与 GIN 索引。同时模型上实现了get_related_recipes()方法cookbook/models.py#L1124-L1137用于找出关联食谱——即被当前食谱的步骤引用step_recipe或食材关联Food 关联的 recipe的其他食谱这是食谱嵌套食谱与食材即食谱设计理念的直接体现也对应 API 侧的 test_api_related_recipe.py 测试。此外各模型普遍继承PermissionModelMixin并通过ScopedManager实现按 Space空间隔离的数据范围管理这正是多个家庭/空间互不干扰的实现基础。部署实战Docker 与 Docker Compose官方明确推荐使用 Docker 部署因为它是唯一被官方维护并定期测试的安装方式见 docs/install/docker.md。镜像版本标签Docker Hub 上的vabene1111/recipes镜像提供多个 taglatest默认镜像不确定时用它beta部分稳定、会不定期更新的版本可能会遇到一些问题develop最前沿的开发版本可能有破坏性变更官方不推荐X.Y.Z每个正式版本都有对应 tag需要固定版本或回退时使用。官方明确警告不支持降级。目前没有任何机制能把数据库迁移回旧版本因此在选择不稳定镜像前请谨慎。单容器快速启动镜像通过内置 nginx 将应用暴露在容器 80 端口docker run -d \ -v $(pwd)/staticfiles:/opt/recipes/staticfiles \ -v $(pwd)/mediafiles:/opt/recipes/mediafiles \ -p 80:80 \ -e SECRET_KEYYOUR_SECRET_KEY \ -e DB_ENGINEdjango.db.backends.postgresql \ -e POSTGRES_HOSTdb_recipes \ -e POSTGRES_PORT5432 \ -e POSTGRES_USERdjangodb \ -e POSTGRES_PASSWORDYOUR_POSTGRES_SECRET_KEY \ -e POSTGRES_DBdjangodb \ --name recipes_1 \ vabene1111/recipes务必替换SECRET_KEY与POSTGRES_PASSWORD占位符Docker Compose推荐从docs/install/docker/下选择适合的 compose 示例plain 直连、traefik-nginx、nginx-proxy、apache-proxy 等下载并编辑.env配置必须设置SECRET_KEY、ALLOWED_HOSTS、POSTGRES_PASSWORD执行docker-compose up -d启动。仓库内 docs/install/docker/plain/docker-compose.yml 提供了最基础的官方示例核心服务是两个容器db_recipespostgres:16-alpine数据卷挂载到./postgresql与web_recipesvabene1111/recipesenv_file指向.env端口 80:80staticfiles与./mediafiles卷挂载并depends_on数据库。这也是理解整个部署拓扑的最简范本。反向代理与必要请求头大多数生产部署会用到反向代理。nginx 反向代理示例location / { proxy_set_header Host $http_host; # try $host instead if this doesnt work proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:8080; # replace port proxy_redirect http://127.0.0.1:8080 https://recipes.domain.tld; # replace port and domain }Apache 示例RequestHeader set X-Forwarded-Proto https Header always set Access-Control-Allow-Origin * ProxyPreserveHost On ProxyRequests Off ProxyPass / http://localhost:8080/ # replace port ProxyPassReverse / http://localhost:8080/ # replace portTandoor 1 与 Tandoor 2 的架构差异Tandoor 1包含 gunicornPython WSGI 服务器但 gunicorn 不适合直接服务媒体文件因此官方一直建议在 Tandoor 前面再架一层 nginx不只是反向代理。gunicorn 默认暴露在 8080 端口。Tandoor 2容器内内置了 nginx对外暴露 80 端口。媒体文件由 nginx 处理其余请求大部分转发给 gunicorn。nginx 默认配置取自仓库根目录的 http.d/ 文件夹如 http.d/Recipes.conf.template可以通过卷挂载到/opt/recipes/http.d覆盖但官方提醒手动修改后将不再收到配置更新。Raspberry Pi 注意事项Tandoor 2 已不再为 arm/v7 架构构建镜像。若在树莓派等设备上遇到问题官方给出的排查步骤是停止所有容器 → 删除本地数据库文件夹通常是 compose 同目录下的postgresql文件夹→ 重新docker-compose up -d→首次启动等待至少 2-3 分钟数据库迁移很耗时→ 用docker logs container_name检查迁移是否完成。配置参数详解所有服务端配置都通过环境变量注入通常集中写在.env文件中完整说明见 docs/system/configuration.md。必选配置SECRET_KEY随机密钥至少 50 字符可用base64 /dev/urandom | head -c50生成用于 Django 各类签名/加密操作必须保密。也支持SECRET_KEY_FILE指向密钥文件ALLOWED_HOSTS默认*生产环境应设置为逗号分隔的域名/IP 列表如recipes.mydomain.com用于防止 HTTP Host Header 攻击数据库参数PostgreSQL 生产推荐变量说明DB_ENGINEdjango.db.backends.postgresql默认或sqlite3生产应始终用 PostgreSQLPOSTGRES_HOST数据库服务器地址Docker 场景用容器名POSTGRES_DB数据库名POSTGRES_PORT端口PostgreSQL 默认5432POSTGRES_USER/POSTGRES_PASSWORD连接用户名 / 密码数据库密码也支持POSTGRES_PASSWORD_FILE文件方式还可以用DATABASE_URL连接字符串engine://username:passwordhost:port/dbname覆盖所有单项配置DB_OPTIONS可附加连接选项如{sslmode:require}。常用可选配置服务层TANDOOR_PORT容器内 nginx 端口默认 80、SCRIPT_NAME子路径部署如/recipes、GUNICORN_WORKERS默认 3、GUNICORN_THREADS默认 2、GUNICORN_TIMEOUT默认 30 秒使用响应较慢的 LLM 时可调大、GUNICORN_MEDIA默认 0不建议让 gunicorn 直接服务媒体文件安全CSRF_TRUSTED_ORIGINS、CORS_ALLOW_ALL_ORIGINS默认 False、HCAPTCHA_SITEKEY/HCAPTCHA_SECRET注册防垃圾、REMOTE_USER_AUTH通过 REMOTE-USER 头认证如 authelia危险非必要勿开、LDAP 系列参数LDAP_AUTH、AUTH_LDAP_SERVER_URI等认证与注册ENABLE_SIGNUP是否开放本地注册、SOCIAL_PROVIDERS与SOCIALACCOUNT_PROVIDERSOAuth/OpenID Connect 社交登录支持SOCIALACCOUNT_PROVIDERS_FILE、SOCIAL_DEFAULT_ACCESS/SOCIAL_DEFAULT_GROUP新社交用户默认加入的空间与组默认guest、ALLAUTH_TRUSTED_PROXY_COUNT信任的反向代理层数默认 1直接访问取 1一层外部代理取 2CDN本地代理取 3外部服务邮件EMAIL_HOST、EMAIL_PORT等配置后自动激活邮箱确认与密码重置、S3 兼容对象存储S3_ACCESS_KEY、S3_SECRET_ACCESS_KEY、S3_BUCKET_NAME可追加S3_ENDPOINT_URL、S3_CUSTOM_DOMAIN等、FDC 营养数据库 APIFDC_API_KEY默认DEMO_KEY限 30 次/小时、AI 集成SPACE_AI_ENABLED、SPACE_AI_CREDITS_MONTHLY、AI_RATELIMIT、AI_ALLOWED_URLS后者用于限定 AI 端点以防 SSRF性能与限制SHOPPING_MIN_AUTOSYNC_INTERVAL购物清单自动同步最小间隔默认 5、DRF_THROTTLE_RECIPE_URL_IMPORT外部 URL 导入限流默认 60/hour、SPACE_DEFAULT_MAX_RECIPES/SPACE_DEFAULT_MAX_USERS/SPACE_DEFAULT_MAX_FILES新建空间默认资源上限、EXPORT_FILE_CACHE_DURATION导出缓存秒数默认 600、zip 导入限制MAX_ZIP_FILE_SIZE10MB、MAX_ZIP_TOTAL_SIZE500MB、MAX_ZIP_FILE_COUNT2000、MAX_ZIP_NESTING_DEPTH2用户默认偏好FRACTION_PREF_DEFAULT分数显示、COMMENT_PREF_DEFAULT评论开关、STICKY_NAV_PREF_DEFAULT吸顶导航、MAX_OWNED_SPACES_PREF_DEFAULT用户可拥有的空间数上限默认 100设 0 禁用调试DEBUG、DEBUG_TOOLBAR、SQL_DEBUG、LOG_LEVEL提交 bug 报告前建议设为 DEBUG外观TZ默认 Europe/Berlin、UNAUTHENTICATED_THEME_FROM_SPACE、FORCE_THEME_FROM_SPACE。导入导出生态与主流食谱软件互操作导入导出是 Tandoor 最具差异化优势的功能之一完整能力对照表与分步操作见 docs/features/import_export.md。官方原则是优先保证导入让用户先把数据迁进来各格式的导出能力会逐步跟进。集成导入导出图片Default内置 ZIP✔️✔️✔️Nextcloud✔️⌚✔️Mealie✔️⌚✔️Chowdown✔️⌚✔️Saffron✔️✔️❌Paprika✔️⌚✔️ChefTap✔️❌❌Pepperplate✔️⌚❌RecipeSage✔️✔️✔️Rezeptsuite.de✔️❌✔️Domestica✔️⌚✔️MealMaster✔️❌❌RezKonv✔️❌❌OpenEats✔️❌⌚Plantoeat✔️❌✔️CookBook Manager✔️⌚✔️Cooklang✔️⌚⌚CopyMeThat✔️❌✔️Mela✔️⌚✔️Cookmate✔️⌚✔️PDF实验性⌚️✔️✔️Gourmet✔️❌✔️Pestle✔️❌✔️✔️已实现❌未实现且不可行/未计划⌚暂未实现几点实战要点Default 内置格式官方首选迁移方式导出物是.zip归档。注意仅上传解压后的.json文件不受支持可能导入报错Tandoor 实例之间迁移请直接使用 ZIP 归档Nextcloud从 Nextcloud 下载Recipes文件夹为Recipes.zip后上传需保持Recipes.zip/Recipes/每个食谱/recipe.json full.jpg的目录结构Mealie需在 Mealie 管理后台创建完整备份仅导出食谱数据会导致不完整导入注意存在 1.0 前后两个版本的导入器且营养信息按每份/每食谱存储需在导入时选择Paprika直接上传.paprikarecipes文件OpenEats需在容器内用manage.py dumpdata导出 JSON 后再导入PDF 导出已移除旧的 pyppeteer 方案被删除现在请直接使用浏览器打印功能CtrlP / CmdP保存食谱为 PDF。代码侧导入器实现位于 cookbook/integration/ 目录default、nextcloud_cookbook、mealie、chowdown、paprika、cooklang 等 20 余个模块导入命令入口在 cookbook/management/commands/import.py并提供 test_url_import.py、test_cooklang_integration.py 等测试保障导入链路。同时docs/features/external_recipes.md 介绍了从网页抓取外部食谱ldjson / microdata的功能。许可与生态自 0.10.0 版本起仓库代码采用GNU AGPL v3 Common Clause 销售例外双重许可详见 LICENSE.md。官方强调软件及其全部功能对所有人永久免费销售例外的原因是作者投入了多年开发时间未来可能推出功能与代码库完全一致、仅托管收费的官方版本收益将反哺项目持续开发。社区生态方面项目提供社区论坛与 Discord 服务器用于支持、交流与开发协作贡献前请先阅读 docs/contribute/guidelines.md 中的贡献指南。小结Tandoor Recipes 是一个定位清晰、功能纵深完整的自托管食谱管理方案以 Django DRF 为后端、PostgreSQL 全文/Trigram 搜索为检索底座、Vue 3 为前端围绕食谱 → 膳食计划 → 购物清单的核心链路叠加菜谱书、分享协作、外部同步、AI 辅助和庞大的导入导出生态。无论你是想把分散在多个软件的食谱集中管理还是想在家庭内搭建一套协作式食谱库都可以基于本仓库快速自建并通过 docs/system/configuration.md 中的丰富配置项按需调整。从源码角度cookbook/models.py 与 cookbook/integration/ 是进一步深入理解其数据模型与互操作能力的最佳起点。【免费下载链接】recipesApplication for managing recipes, planning meals, building shopping lists and much much more!项目地址: https://gitcode.com/GitHub_Trending/re/recipes创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考