Mealie 3.30.0 常用 CLI 命令与工具详解

Mealie v3.30.0 命令行运维面实测:容器 venv 42 项工具清单与 run.sh/healthcheck.sh 源码解读(无管理型 CLI,mealie 入口即起服)、curl 全链路 API 闭环(登录/CRUD/长期 Token/敏感端点 accept-language 传密码)、备份恢复三条路实测(应用内两段式 fileToken 下载+restore、SQLite 冷拷贝容器内校验、pg_dump/pg_restore 临时库验证)、日常运维速查。

MealieMealie自托管DockerPythonFastAPIPostgreSQL2026/11/02

Mealie 3.30.0 常用 CLI 命令与工具详解

目标:讲清 Mealie v3.30.0 的"命令行运维面"到底有什么——先纠正一个常见预期:Mealie 没有功能型管理 CLI(mealie 入口就是起服务,子命令、参数管理一概没有),日常管理手段是三层:容器内 venv 工具链、REST API(curl 可完成全部管理动作)、数据库原生工具(pg_dump / SQLite 文件)。本文所有命令与回显均为本地实测(2026-11-02),含 API 全链路(登录→CRUD→长期令牌→备份下载→恢复)与两路备份恢复闭环。部署见《Mealie 3.30.0 Docker Compose 部署指南》,变量含义见《Mealie 3.30.0 配置参数详解》。

一、环境信息

  • 实例:mealie-3.30.0-app(:8152,PG 形态)、mealie-3.30.0-sqlite(:8157,SQLite 形态)、mealie-3.30.0-db(postgres:17)
  • 镜像:ghcr.io/mealie-recipes/mealie:v3.30.0,容器内 Python 3.14.8,venv 位于 /opt/mealie
  • API 闭环实测在 SQLite 实例做(PG 实例默认凭据已被前任改掉、401 复现,留作改密生效证据)
  • OpenAPI 规格实测 195 个路径(python 统计 openapi.json 的 paths 键数:total paths: 195)

二、容器命令面:venv 工具链

2.1 /opt/mealie/bin 全量清单(实测 docker exec mealie-3.30.0-app ls /opt/mealie/bin)

Activate.ps1   cffi-gen-src       fastapi      markdown_py  pip     rdf2dot              tqdm
activate       csv2rdf            html2text    mealie       pip3    rdfgraphisomorphism  uvicorn
activate.csh   curl-cffi          httpx        nltk         pip3.14 rdfpipe              watchfiles
activate.fish  dotenv             httpx2       normalizer   python  rdfs2dot             websockets
alembic        extruct            idna         numpy-config python3 slugify              yt-dlp
apprise        f2py               mako-render  pint-convert python3.14 sparqlquery       𝜋thon

(ls /opt/mealie/bin 实测输出共 42 项,上为按列重排、未增删。)按用途归类:

工具用途(对运维的意义)
mealie服务入口本体,entry 源码即 from mealie.main import main 后调用(实测查看)。mealie --help 不打印帮助而是直接尝试起服,报 ERROR [Errno 98] Address already in use (while attempting to bind on address ('::', 9000))——确认它无子命令、无参数解析,只是启动器
uvicorn / fastapi底层 web 服务器与框架 CLI,排障时可单独起服定位问题
alembic数据库迁移工具。升级/排障时迁移日志(Running upgrade ...)即它输出,head 为 071e03b4f851(v3.30.0 实测)
apprise通知库 CLI(Mealie 的 webhook/通知底座)
curl-cffi / httpx / extruct / html2text / markdown_pyURL 抓取栈:浏览器 TLS 指纹伪装、HTTP 客户端、微数据解析、HTML 转换
nltk / pint-convert食材解析(NLTK 模型在 /nltk_data/)与单位换算 CLI
yt-dlp视频转写导入下载器(配 YTDLP_COOKIEFILE)
slugify / dotenv / tqdm / watchfiles / websockets杂项工具
python3.14 / pip容器内没有 sqlite3 和 pg_dump 二进制(实测确认)。查 SQLite 库要用 python -c "import sqlite3; ...";PG 客户端工具在 postgres 容器里做

2.2 /app 下的三个脚本(实测全文)

容器工作目录 /app 只有:data/、run.sh、healthcheck.sh、setup_nltk_data.sh。

run.sh(entrypoint,PID 1 实际执行者)关键逻辑:

PUID=${PUID:-911}
PGID=${PGID:-911}
...
change_user() {
    if [ "$(id -u)" = $PUID ]; then
        echo "User uid: $PUID ..."          # 已是目标用户,直接继续
    elif [ "$(id -u)" = "0" ]; then
        add_user                             # groupmod/usermod -o 改 abc 用户
        chown -R $PUID:$PGID /app
        echo "Switching to dedicated user"
        exec gosu $PUID "$BASH_SOURCE" "$@"  # root 启动则降权重跑自身
    fi
}
init() { cd /app; . /opt/mealie/bin/activate; }   # 激活 venv
load_secrets() { ... }   # 见下
change_user
init
load_secrets || exit 1
exec mealie
  • load_secrets 的白名单即 Docker Secrets 支持的 16 个变量(POSTGRES_* 六项、SMTP_* 四项、LDAP_SERVER_URL/LDAP_QUERY_PASSWORD、OIDC_CONFIGURATION_URL/OIDC_CLIENT_ID/OIDC_NATIVE_CLIENT_ID/OIDC_CLIENT_SECRET):任一 *_FILE 指向缺失/不可读/非普通文件 → 打 ERROR: $file_var must point to a readable regular file. 并退出(load_secrets || exit 1);空内容打 WARN 后以空值覆盖。
  • 最后一行 exec mealie——整个容器的生命周期就是这一个 uvicorn 进程。

healthcheck.sh(镜像健康探针):

PORT="${API_PORT:-9000}"
if [ -n "$TLS_CERTIFICATE_PATH" ] && [ -n "$TLS_PRIVATE_KEY_PATH" ]; then
  PROTO="https"; else PROTO="http"; fi
curl -fsk "${PROTO}://127.0.0.1:${PORT}/api/app/about" > /dev/null

宿主机侧等价探活命令(实测可用):

docker inspect --format '{{.State.Health.Status}}' mealie-3.30.0-sqlite   # healthy
curl -s http://127.0.0.1:8157/api/app/about | head -c 200                  # version v3.30.0

三、API 工具链:curl 完成全部管理动作(实测闭环)

Mealie 的管理面就是 REST API,Swagger 文档在 /docs(API_DOCS=True 时)。以下链条在 SQLite 实例 :8157 全程实测走通。

3.1 登录取 token

curl -s -X POST http://127.0.0.1:8157/api/auth/token \
  -d "username=changeme@example.com&password=MyPassword"

→ 200,access_token 为 JWT(form 表单、非 JSON 体)。exp = 签发时刻 + TOKEN_TIME(48) 小时。后续请求带 -H "Authorization: Bearer $TOKEN"。

3.2 食谱 CRUD

# 创建 → 201,返回 slug 字符串
curl -s -X POST .../api/recipes -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"name":"D1 验证食谱"}'
"d1-yan-zheng-shi-pu"

# 读取
curl -s .../api/recipes/d1-yan-zheng-shi-pu -H "Authorization: Bearer $TOKEN"
# → name/slug/id=93ebab41-9206-4294-86e0-3123a760304c

# 更新 → 200,回显全量对象
curl -s -X PUT .../api/recipes/d1-yan-zheng-shi-pu -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d @recipe_body.json
# → desc=API 更新验证、ing=['2 个鸡蛋']、steps=['步骤1']

# 删除 → 200
curl -s -X DELETE .../api/recipes/d1-yan-zheng-shi-pu -H "Authorization: Bearer $TOKEN"

URL 抓取导入(需目标地址过 SSRF 白名单,见配置篇 HTTP_ALLOW_LIST):POST /api/recipes/create-url -d '{"url":"..."}' → 返回 slug(PG 实例实测导入内网测试页得 mapo-tofu,回显含 orgURL、3 步骤、5 食材原文入 note、totalTimeSeconds=1500)。食材/单位是独立字典库:POST /api/foods、POST /api/units 先建后引用(实测"克"id=f6881f62...,standardUnit=gram,abbreviation=g;食谱显示自动标准化为"3 克 盐")。

3.3 长期 API Token(脚本/集成用)

curl -s -X POST .../api/users/api-tokens \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -H "accept-language: MyPassword" \
  -d '{"name":"d1-cli"}'

→ 201,返回一个 long_token: true 的 JWT,实测有效期 5 年(iat 1793571940 → exp 1951251940)。两个要点:① 该端点属敏感操作,必须把当前用户密码放在 accept-language 头里二次确认(官方设计,备份/删除类管理端点同理);② 拿到的 token 直接当 Bearer 用,实测 GET /api/recipes → total: 1,可长期无人值守调用(Home Assistant/n8n 集成即此路径)。用完回收:DELETE /api/users/api-tokens/1 → {"tokenDelete":"d1-cli"}。

四、备份与恢复:三条路(全部实测闭环)

4.1 应用内备份(API/UI 同底座,推荐)

# 创建备份(同样要 accept-language 传密码)
curl -s -X POST .../api/admin/backups -H "Authorization: Bearer $TOKEN" -H 'accept-language: MyPassword'
{"message":"Backup created successfully","error":false}

# 列出
curl -s .../api/admin/backups -H "Authorization: Bearer $TOKEN"
{"imports":[{"name":"mealie_v3.30.0_2026.11.01.22.25.53.zip","date":"2026-11-01T22:25:53.513967Z","size":"25.45 KB"}],"templates":[]}

下载是两段式(易踩坑):GET /api/admin/backups/<name>?password=<pwd> 返回的不是 zip,而是一个 252B 的 JSON:{"fileToken":"..."}(实测确认);再 GET /api/utils/download?token=<fileToken> 才拿到 zip 本体(实测 26063B)。fileToken 有效期 30 分钟。zip 内容实测:database.json(全库 JSON dump)+ .secret + .session_secret + profile.webp——备份包含签名密钥,恢复后旧 token 仍有效,同时它属敏感文件,外传需加密。

恢复:POST /api/admin/backups/<name>/restore(accept-language 传密码)→ {"message":"Restore successful","error":false}。实测恢复后 GET /api/recipes total: 1,数据存活、原 token 仍可用。

4.2 SQLite 冷拷贝

cp sqlite-data/mealie.db d1-sqlite-coldcopy.db     # 1523712B

校验必须在容器内做(实测宿主机 python3.12 的 sqlite3 模块损坏:undefined symbol: sqlite3_deserialize):

docker exec mealie-3.30.0-sqlite python -c "
import sqlite3; c=sqlite3.connect('...coldcopy.db')
print('tables:', len(c.execute(\"select name from sqlite_master where type='table'\").fetchall()))"
# tables: 70, recipes: 1, journal_mode: delete

journal_mode=delete 印证 SQLITE_MIGRATE_JOURNAL_WAL 默认 False。冷拷贝在低写入时刻做;恢复=停容器、覆盖 mealie.db、起容器。

4.3 PostgreSQL:pg_dump / pg_restore

镜像内无 PG 客户端,在 postgres 容器里操作:

docker exec mealie-3.30.0-db pg_dump -U mealie --format=custom -f /tmp/mealie-pg.dump mealie
docker cp mealie-3.30.0-db:/tmp/mealie-pg.dump .    # 235221B

dump 头实测:TOC Entries: 629、Dumped from database version: 17.11 (Debian)。恢复验证闭环(不动生产库,恢复到临时库):

docker exec mealie-3.30.0-db psql -U mealie -d postgres -c "CREATE DATABASE mealie_restore_test"
docker exec mealie-3.30.0-db pg_restore -U mealie -d mealie_restore_test /tmp/mealie-pg.dump
# \dt 计数 = 70 表;recipes 表回显 fan-qie-chao-dan|番茄炒蛋、mapo-tofu|Mapo Tofu
docker exec mealie-3.30.0-db psql -U mealie -d postgres -c "DROP DATABASE mealie_restore_test"

\dt 实测还能看到 pg_trgm 扩展——PG 形态模糊搜索的实现来源(见配置篇)。

五、日常运维速查(实测可用)

# 起停/升级
docker compose up -d                      # 改 env 后重建生效(无热加载)
docker compose pull && docker compose up -d   # 升级镜像 tag 后自动跑增量迁移
docker logs -f mealie-3.30.0-app          # 日志同落 data/mealie.log

# 探活/版本
curl -s http://127.0.0.1:8152/api/app/about | python3 -m json.tool | head

# 生效配置核对:首启日志的 APP SETTINGS dump(见部署篇第四节④)
docker logs mealie-3.30.0-app | sed -n '/APP SETTINGS/,/APP FEATURES/p'

# 容器内查 SQLite(无 sqlite3 二进制,用 python)
docker exec mealie-3.30.0-sqlite python -c "import sqlite3;print(sqlite3.connect('/app/data/mealie.db').execute('select count(*) from recipes').fetchone())"

# PG 就绪探针
docker exec mealie-3.30.0-db pg_isready

六、参考链接

Mealie 3.30.0 常用 CLI 命令与工具详解 - Quzuo