Mealie 3.30.0 配置参数详解
Mealie v3.30.0 全部后端环境变量按必配/默认即用/条件启用三级分类详解:General/安全/数据库/SMTP/Webworker/TLS/LDAP/反代认证/OIDC/AI抓取/主题品牌/Docker Secrets 十二组,官方默认值与首启 APP SETTINGS dump 逐项对照,LOG_LEVEL、HTTP_ALLOW_LIST、TOKEN_TIME、DAILY_SCHEDULE_TIME 等关键行为改参闭环实测。
Mealie 3.30.0 配置参数详解
目标:把 Mealie v3.30.0 的全部后端配置变量按"必配 / 默认即用 / 条件启用"分类讲透——每个分组给出官方默认值、生效条件与本地实测证据。口径来源有二:官方 Backend Configuration 文档全量抓取(1007 行),以及本地实例首次启动打印的 APP SETTINGS 全量 dump(90+ 键)逐项对照;关键行为(LOG_LEVEL、HTTP_ALLOW_LIST、TOKEN_TIME、DAILY_SCHEDULE_TIME、API_HOST、.secret 持久性)均做了改参闭环实测。部署流程见本专栏《Mealie 3.30.0 Docker Compose 部署指南》。
一、环境信息
- 版本:
ghcr.io/mealie-recipes/mealie:v3.30.0(GIT_COMMIT_HASH=9552df62118224a377d9c9b0a62706a62220ab86,APP SETTINGS dump 实测) - 官方文档:docs.mealie.io Backend Configuration 页(查询日期 2026-11-02,全文已存档对照)
- 实测实例:PG 形态
:8152、SQLite 形态:8157(改参闭环在 SQLite 实例做,避免影响 PG 取证现场) - 配置加载方式:全部通过环境变量(compose
environment:/docker run -e/ Docker Secrets_FILE),无配置文件;改环境变量后需重建容器生效
二、配置如何生效与如何核对(实测)
- 改参闭环实测:给 SQLite 实例 compose 加
LOG_LEVEL: debug→docker compose up -d(Recreated)→ 日志立即出现DEBUG行(Migration not needed.、Registering daily callback: purge_expired_tokens等);删掉该行再up -d→grep -c '^DEBUG'归 0,回到 INFO。结论:环境变量改动必须经容器重建生效,运行中改 compose 不热加载。 - 核对生效值:首次启动日志的
------APP SETTINGS------段会打印全量最终配置(JSON,90+ 键),是"变量到底读没读到"的权威口径。实测踩坑:旧启动日志里HTTP_ALLOW_LIST为空串,而 compose 已配置——原因是容器启动早于 compose 编辑;用docker inspect查当前容器 Env 确认HTTP_ALLOW_LIST=10.89.56.0/24已注入,重建后日志与 inspect 一致。 - 密钥持久性:
.secret/.session_secret落在/app/data卷内,实测容器 recreate 后旧 access_token 仍有效(JWT 签名密钥未变)。删数据卷 = 全部 token 失效 + 需重新初始化。 - 主题/品牌类变量只在启动时读一次(官方明确),改后同样要重启容器;前端浏览器可能缓存旧主题,需清 cookie。
三、变量总览:必配 / 默认即用 / 条件启用
| 分类 | 变量 | 说明 |
|---|---|---|
| 必配(3 个) | BASE_URL、TZ、PUID/PGID(视宿主机目录属主) | BASE_URL 影响通知与 OIDC 回调;TZ 默认 UTC 必改;PUID/PGID 默认 911,与数据目录属主对齐 |
| 默认即用 | DB_ENGINE=sqlite、API_PORT=9000、TOKEN_TIME=48、ALLOW_SIGNUP=false、LOG_LEVEL=info、DAILY_SCHEDULE_TIME=23:45、DEFAULT_GROUP=Home、DEFAULT_HOUSEHOLD=Family、API_DOCS=True、ALLOW_PASSWORD_LOGIN=true | 单机自用可一行不改直接跑 |
| 条件启用 | POSTGRES_*(选 PG 时)、SMTP_*(要发邮件时)、LDAP_* / OIDC_* / REVERSE_PROXY_AUTH_*(接 SSO 时)、SCRAPER_PROXY_URL / SCRAPER_FLARESOLVERR_URL(抓取被反爬时)、HTTP_ALLOW_LIST(要抓内网 URL 时)、THEME_* / BRANDING_*(换肤时)、TLS_*(不走反代直接 https 时) | 各节展开 |
四、General 与监听
| 变量 | 默认 | 说明(含实测) |
|---|---|---|
PUID / PGID | 911 | 容器运行身份。root 启动时 run.sh 用 gosu 降权并 chown /app;非 root 启动则要求目录属主已匹配 |
DEFAULT_GROUP / DEFAULT_HOUSEHOLD | Home / Family | 初始化默认组与家务单元名(APP SETTINGS 实测一致) |
BASE_URL | http://localhost:8080 | 对外可达地址,用于通知链接与 OIDC 回调。单机写 http://127.0.0.1:<映射端口> |
TOKEN_TIME | 48 | 登录会话小时数,上限 9600(400 天)。实测签发的 JWT exp = iat+48h,吻合 |
API_PORT | 9000 | 后端监听端口。官方明确 Docker 形态不要改(healthcheck.sh 也读它) |
API_HOST | 空 | 监听地址。空=自动开一个 IPv6 dual-stack socket(实测日志 Uvicorn running on socket ('::', 9000),IPv4 同时可达);可显式 0.0.0.0/127.0.0.1/::/::1。端口被占或无权限绑定会直接启动失败 |
API_DOCS | True | 是否暴露 /docs、/redoc。公网部署建议关 |
TZ | UTC | 必设本地时区。实测 DAILY_SCHEDULE_TIME: 23:45 + TZ=Asia/Shanghai → 日志 Daily tasks scheduled for 2026-11-02 15:45:00+00:00(=23:45 CST),排期按本地时间换算 |
ALLOW_SIGNUP | false | 自 v1.4.0 因安全评审改为默认 false。注意:不拦截内置默认管理员,首登改密仍是必须动作 |
ALLOW_PASSWORD_LOGIN | true | 是否显示用户名密码登录框。仅 OIDC 场景才考虑关 |
LOG_LEVEL | info | critical/error/warning/info/debug。改参闭环实测见第二节 |
LOG_CONFIG_OVERRIDE | null | 自定义日志配置文件路径 |
DAILY_SCHEDULE_TIME | 23:45 | 每日任务时间,HH:MM,按服务器本地时间而非 UTC |
五、安全
| 变量 | 默认 | 说明(含实测) |
|---|---|---|
HOST_IP | * | Uvicorn 信任哪些来源地址送来的 X-Forwarded-For/X-Forwarded-Proto。默认 * 信任所有来源的转发头(可伪造真实 IP),官方要求仅在访问受限时使用;反代场景应设为代理 IP/CIDR(如 127.0.0.1,10.42.1.0/24),设空串=不信任任何转发头。APP SETTINGS 实测默认值 * |
SECURITY_MAX_LOGIN_ATTEMPTS | 5 | 连错次数上限,超过锁号 |
SECURITY_USER_LOCKOUT_TIME | 24 | 锁定时长(小时) |
ALLOWED_IFRAME_HOSTS | 空 | 食谱内容里允许内嵌 <iframe> 的额外主机(内置白名单已含 YouTube/Vimeo,子域自动包含,仅 https)。加域名=向包括匿名访客在内的所有人渲染该来源嵌入,谨慎 |
HTTP_ALLOW_LIST | 空 | 服务端发起请求(URL 抓取、webhook、recipe actions、OIDC 头像拉取)允许触达的私网/内网 CIDR 或主机。实测:不放行时贴内网 URL 导入被 SSRF 防护拦截;设 10.89.56.0/24 重建后 POST /api/recipes/create-url 成功(返回 slug mapo-tofu) |
HTTP_DISALLOW_LIST | 空 | 永不可达的主机/CIDR,优先级高于 ALLOW_LIST,即使公网地址也拦 |
六、数据库
| 变量 | 默认 | 说明(含实测) |
|---|---|---|
DB_ENGINE | sqlite | sqlite 或 postgres。不设即 SQLite(docker run 实测日志 "DB_ENGINE": "sqlite") |
SQLITE_MIGRATE_JOURNAL_WAL | False | true 则把 SQLite journal 模式切 WAL(多并发/远端存储如 Ceph 场景)。实测默认库 journal_mode=delete(容器内 python sqlite3 查询确认),与默认值吻合;库内共 70 张表 |
POSTGRES_USER | mealie † | PG 用户名 |
POSTGRES_PASSWORD | mealie † | PG 密码。生产必改或用 secret |
POSTGRES_SERVER | postgres † | PG 地址(compose 服务名即可) |
POSTGRES_PORT | 5432 † | PG 端口 |
POSTGRES_DB | mealie † | 库名 |
POSTGRES_URL_OVERRIDE | None † | 整条 DSN 直接覆盖上面五项 |
† 表示支持 _FILE Docker Secrets 形态(见第十一节)。PG 形态首启实测:alembic 一次跑完 62 个 upgrade 步骤到 head 071e03b4f851,其中 postgres fuzzy search 步骤与库内 pg_trgm 扩展即模糊搜索的实现(SQLite 形态无此能力)。
七、邮件(SMTP)
| 变量 | 默认 | 说明 |
|---|---|---|
SMTP_HOST | None † | 必填项 |
SMTP_PORT | 587 † | 必填项 |
SMTP_FROM_NAME | Mealie | 必填项 |
SMTP_FROM_EMAIL | None | 必填项 |
SMTP_AUTH_STRATEGY | TLS | 必填项,可选 TLS/SSL/NONE |
SMTP_USER / SMTP_PASSWORD | None † | 可选,但必须成对设置 |
用途:邀请注册、找回密码、膳食计划通知。缺必填项不会启动失败,而是功能降级——APP FEATURES 实测打印:--------==SMTP==-------- Enabled: False Reason: Missing required values for ['SMTP_HOST', 'SMTP_FROM_EMAIL']。排查"邮件不发"先看这行。
八、Webworker 与 TLS
| 变量 | 默认 | 说明 |
|---|---|---|
UVICORN_WORKERS | 1 | web 进程数。官方警告:调高可能引发内存泄漏类问题,多人卡顿前建议保持默认;APP SETTINGS 另见 WORKER_PER_CORE=1 |
TLS_CERTIFICATE_PATH / TLS_PRIVATE_KEY_PATH | None | 仅不挂反代直接对外 https 时用。两者同时设置后 healthcheck.sh 自动改用 https://127.0.0.1:9000/api/app/about 探针(脚本实测,-k 跳过自签证书校验) |
九、认证外挂(LDAP / 反代头 / OIDC)
三套都默认关闭,按需启用;首启 APP FEATURES 段会逐个打印判定结果(实测 LDAP ... Reason: LDAP_AUTH_ENABLED is false、OIDC ... Reason: OIDC_AUTH_ENABLED is false)。
LDAP(LDAP_AUTH_ENABLED=False 起):LDAP_SERVER_URL†、LDAP_BASE_DN、LDAP_QUERY_BIND/LDAP_QUERY_PASSWORD†(不设则匿名 bind)、LDAP_USER_FILTER/LDAP_ADMIN_FILTER、LDAP_ID_ATTRIBUTE=uid/LDAP_NAME_ATTRIBUTE=name/LDAP_MAIL_ATTRIBUTE=mail、LDAP_TLS_INSECURE=False、LDAP_TLS_CACERTFILE、LDAP_ENABLE_STARTTLS=False。在内置账号之外叠加 LDAP 验证。
Reverse Proxy Auth(REVERSE_PROXY_AUTH_ENABLED=False 起):信任已认证反代(Authelia/Authentik/oauth2-proxy/Tailscale Serve)转发的用户名头 REVERSE_PROXY_AUTH_HEADER=X-Forwarded-User,访问登录页即自动登入;REVERSE_PROXY_AUTH_SIGNUP_ENABLED=False 控制首见用户自动建号。官方强警告:必须让反代始终覆盖/剥离该头且应用不可被绕过直连,并设置 REVERSE_PROXY_AUTH_SECRET(经 REVERSE_PROXY_AUTH_SECRET_HEADER=X-Mealie-Reverse-Proxy-Secret 传递),否则任何人可伪造头部冒充管理员。
OIDC(OIDC_AUTH_ENABLED=False 起,v1.4.0 引入):核心四件套 OIDC_CONFIGURATION_URL† / OIDC_CLIENT_ID† / OIDC_CLIENT_SECRET†(v2.0.0 起支持 secret)+ 回调地址依赖 BASE_URL。行为开关:OIDC_SIGNUP_ENABLED=True(首登建号)、OIDC_REQUIRES_EMAIL_VERIFICATION=True(v3.21.0 起要求 email_verified claim,仅 IdP 不发该 claim 时关)、OIDC_AUTO_REDIRECT=False(True 则跳过登录页直达 IdP,加 ?direct=1 可绕回)、OIDC_PROVIDER_NAME=OAuth(登录按钮文案)、OIDC_REMEMBER_ME=False。字段映射:OIDC_USER_CLAIM=email、OIDC_NAME_CLAIM=name、OIDC_GROUPS_CLAIM=groups、OIDC_USER_GROUP/OIDC_ADMIN_GROUP(按组放行/提权)。杂项:OIDC_SCOPES_OVERRIDE(至少 openid profile email)、OIDC_TLS_CACERTFILE、OIDC_VERIFY_X509_STRICT=True(Python 3.13 收紧 X509 校验导致部分 CA 证书失败时设 False)、OIDC_CLIENT_TIMEOUT=default(5.0s;None 关闭超时)、OIDC_NATIVE_CLIENT_ID†/OIDC_NATIVE_CONFIDENTIAL=True(Google/Microsoft 等要求独立原生客户端时配)。
十、AI 与抓取器(Scraper)
| 变量 | 默认 | 说明 |
|---|---|---|
YTDLP_COOKIEFILE | None | 视频转写导入(yt-dlp 下载)需登录内容时提供 cookie 文件 |
SCRAPER_PROXY_URL | None | 抓取与图片下载的统一出口代理(http://user:pass@host:port),换 IP 信誉绕 IP 封禁 |
SCRAPER_PROXY_MODE | always | always 全走代理;fallback 先直连、被拦才走代理(按流量计费代理用);无法识别的值按 always |
SCRAPER_FLARESOLVERR_URL | None | 自建 FlareSolverr 地址(如 http://flaresolverr:8191),最后手段解 JS/Cloudflare 挑战;只用于食谱页,图片下载永远不走它 |
SCRAPER_FLARESOLVERR_TIMEOUT | 60 | 单次挑战最长秒数 |
官方抓取升级策略(逐步 escalate,首个成功即停):① 直连+轮换浏览器 TLS 指纹(内置,无需配置,多数站点够用)→ ② 代理(设了 SCRAPER_PROXY_URL 才参与)→ ③ FlareSolverr(设了 URL 且仍被拦才用)。真实 404 视为错误,不会重试后两级。AI 供应商(OpenAI 兼容,生成食谱/图像解析)不走环境变量,在管理界面配置(ai providers 表,v3.30.0 迁移含 backfill missing ai provider settings)。
十一、主题与品牌
THEME_LIGHT_PRIMARY=#E58325、THEME_LIGHT_ACCENT=#007A99、THEME_LIGHT_SECONDARY=#973542、THEME_LIGHT_SUCCESS=#43A047、THEME_LIGHT_INFO=#1976D2、THEME_LIGHT_WARNING=#FF6D00、THEME_LIGHT_ERROR=#EF5350;深色对应THEME_DARK_*同值。共 14 个变量,APP SETTINGS dump 的theme对象与默认值逐项吻合(实测)。- YAML 引号坑(官方明示):
KEY: '#E58325'必须带引号,否则#被 YAML 当注释吃掉;序列写法KEY=#E58325则不要引号。改了不生效先查这里,再清浏览器 cookie。 BRANDING_NAME=Mealie、BRANDING_LOGO_PATH(容器内路径非 URL,需 bind-mount 图片文件进去;路径无效/类型不认识则静默回退内置 logo)。只改顶栏名/页签标题/PWA 名与 logo/favicon,翻译文案与邮件不受影响。同样仅启动时读取一次。
十二、Docker Secrets(_FILE 模式)
自 v2.4.2 起,官方带 † 标记的变量支持追加 _FILE 后缀从文件读值。实测容器内 /app/run.sh 的 secret_supported_vars 白名单共 16 个,与文档 † 完全一致:
POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_SERVER / POSTGRES_PORT / POSTGRES_DB / POSTGRES_URL_OVERRIDE
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASSWORD
LDAP_SERVER_URL / LDAP_QUERY_PASSWORD
OIDC_CONFIGURATION_URL / OIDC_CLIENT_ID / OIDC_NATIVE_CLIENT_ID / OIDC_CLIENT_SECRET
规则(文档 + run.sh 源码互证):
- 基础变量与
_FILE同时设置时,secret 永远优先; _FILE必须指向可读的常规文件,缺失/非普通文件/不可读 → 启动直接报错退出(run.shload_secrets || exit 1,即使基础变量也设了);- 文件内容尾部换行会被去掉;结果为空则打 WARN 并以空值覆盖基础变量;
- 文件必须在容器降权后的运行用户(默认 911 或你的 PUID)下可读;K8s Secret 的符号链接形态支持(target 为可读常规文件即可);
- 未使用的可选项不要设空
_FILE,直接省略; - 官方建议共享环境至少把
POSTGRES_PASSWORD、SMTP_PASSWORD、LDAP_QUERY_PASSWORD三个转成 secret。
compose 用法示例(官方口径):secrets: 块声明文件 → 服务挂 secrets: → 环境写 POSTGRES_PASSWORD_FILE: /run/secrets/postgres-password(Docker 挂载到 /run/secrets/)。
十三、参考链接
- 官方后端配置文档:https://docs.mealie.io/documentation/getting-started/installation/backend-config (查询日期 2026-11-02,全量口径已对照)
- 官方文档 · 更新指南:https://docs.mealie.io/documentation/getting-started/update-guide
- 官方文档 · 认证(LDAP/OIDC):https://docs.mealie.io/documentation/usage/authentication/
- 官方仓库:https://github.com/mealie-recipes/mealie
- 本专栏部署篇:《Mealie 3.30.0 Docker Compose 部署指南》;运维篇:《Mealie 3.30.0 常用 CLI 命令与工具详解》