Mayan EDMS 常用命令与运维实战
Mayan EDMS 4.12.2 运维实战:管理命令全景(21 组 44 条实测清单)、REST API Token 认证实测(文档上传/OCR/全文检索/抽屉/标签/事件)、数据库与应用卷备份、队列观测与排障实录。
Mayan EDMS 常用命令与运维实战
目标:盘点 Mayan EDMS 4.12.2 的日常运维入口——管理命令行(21 组 44 条命令全清单)、REST API(Token 认证 + 文档上传/OCR/检索/归档全链路 curl 实测)、备份恢复与故障排查。所有命令与回显均在 4.12.2 实测环境逐条执行(部署过程见 《Mayan EDMS Docker Compose 部署实战》)。
一、环境信息
- Mayan EDMS:4.12.2(官方
s4.12镜像,all_in_one 形态,2026-10-28 实测) - 管理员:
admin / q1w2e3r4(首启自动创建,AUTOADMIN_*变量预设) - 已初始化对象:文档类型
Contract(id 2)、抽屉2026 Contracts(id 1)、标签ocr-verified(id 1) - 实测文档:
QZ-2026-0428 Purchase Contract(id 3,英文 OCR)、QZ-2026-0429 中文采购合同(id 4,中文 OCR) - 服务入口形态:官方 Compose 部署下,管理命令经应用服务控制台执行
entrypoint.sh run_command <命令>;run_command会先走一遍入口脚本初始化段(依赖探活、uid/gid、字体缓存)再执行目标命令
二、管理命令全景(21 组 44 条实测清单)
entrypoint.sh run_command help 实测输出(Mayan EDMS 4.12.2):
| 分组 | 命令 | 用途 |
|---|---|---|
| appearance | appearance_prepare_static | 静态资源准备 |
| auth | changepassword、createsuperuser | 改密 / 建管理员 |
| authentication_otp | authentication_otp_disable/_initialize/_status | 双因素 OTP 管理 |
| authtoken | drf_create_token | 创建/获取 REST API Token |
| autoadmin | autoadmin_create | 手动触发自动管理员创建 |
| axes | axes_list_attempts、axes_reset(_failure_logs/_ip/_ip_username/_logs/_username) | 登录限流(防爆破)查看与解锁 |
| common | common_generate_random_secret_key、common_initial_setup、common_perform_upgrade | 随机密钥生成 / 初始化 / 升级迁移 |
| contenttypes | remove_stale_contenttypes | 清理失效内容类型 |
| databases | makemigrations | 生成迁移(开发用) |
| dependencies | dependencies_check/_check_version/_generate_requirements/_install/_show_version/_uninstall | 依赖核对与管理 |
| django(核心) | check、compilemessages、createcachetable、dbshell、diffsettings、dumpdata、flush、inspectdb、loaddata、makemessages、migrate、optimizemigration、sendtestemail、shell、showmigrations、sqlflush、sqlmigrate、sqlsequencereset、squashmigrations、startapp、startproject、test、testserver | Django 标准命令 |
| documentation | documentation_features_generate | 生成功能文档 |
| drf_spectacular | spectacular、(rest_framework)generateschema | 导出 OpenAPI Schema |
| dynamic_search | search_index_objects、search_initialize、search_reindex、search_status、search_upgrade | 全文检索索引管理 |
| file_caching | file_caching_purge_cache | 清预览缓存 |
| lock_manager | lock_manager_purge_locks | 清孤儿锁 |
| mayan_statistics | statistics_purge | 清统计数据 |
| mirroring | mirroring_mount_cabinet、mirroring_mount_index | 抽屉/索引 FUSE 镜像挂载 |
| permissions | permissions_purge | 清权限残留 |
| platforms | platforms_template | 平台模板 |
| sessions | clearsessions | 清过期会话 |
| smart_settings | settings_revert、settings_save、settings_show | 运行期设置查看/保存/回退 |
| staticfiles | collectstatic、findstatic、runserver | 静态资源与开发服务器 |
| storage | storage_process、storage_shard_files | 存储处理与分片 |
| task_manager | task_manager_purge_periodic_tasks | 清理周期任务残留 |
版本差异提醒:老版本文档里的
showsettings在 4.12.2 已不存在(实测报Unknown command,提示改用diffsettings);设置查看以settings_show为准。
三、关键管理命令实测
3.1 drf_create_token:创建 API Token
entrypoint.sh run_command drf_create_token admin
实测回显(末行):
5626fcf3f8966638b9228234974f89902efeda4d
对同一用户重复执行返回同一个 Token(幂等)。此后所有 API 调用带请求头 Authorization: Token <值>。
3.2 settings_show:查看生效设置
entrypoint.sh run_command settings_show
实测摘录:
OCR_AUTO_OCR: true
OCR_BACKEND: mayan.apps.ocr.backends.tesseract.Tesseract
OCR_BACKEND_ARGUMENTS:
AUTOADMIN_EMAIL: autoadmin@example.com
AUTOADMIN_PASSWORD: q1w2e3r4
AUTOADMIN_USERNAME: admin
CELERY_BROKER_URL: amqp://mayan:mayanrabbitpass@rabbitmq:5672/mayan
注意:输出含明文密码,勿外贴。参数含义见 《Mayan EDMS 配置参数详解》。
3.3 search_status:检索索引状态
entrypoint.sh run_command search_status
实测回显(文档入库后):
Document type 2
Document version 2
Document version page 2
...
User 1
每类对象一行计数。文档上传后若检索无结果,先看这里计数是否已增长(索引是异步更新的)。
3.4 dependencies_check:依赖完整性核对
entrypoint.sh run_command dependencies_check
实测尾部回显:
* sh Class: Python | Version: ==2.2.6 | App: Common | Check: True
* signature_pad Class: JavaScript | Version: =4.2.0 | App: Signature captures | Check: True
* whitenoise Class: Python | Version: ==6.12.0 | App: Platforms | Check: True
升级后排查依赖错乱的第一条命令,逐项给出 Check: True/False。
3.5 common_generate_random_secret_key:生成随机密钥
entrypoint.sh run_command common_generate_random_secret_key
实测回显:
qj_-++8(v&(4i^armj0$@gxn)^q40=ys0p&v(l3b=%n*l50f@b
可直接用于生产 SECRET_KEY 等密钥场景。
3.6 数据库直查(psql)
数据库控制台内直查对象计数,验证数据落库:
psql -U mayan mayan -c "SELECT 'documents' t, count(*) FROM documents_document UNION ALL SELECT 'versions', count(*) FROM documents_documentversion UNION ALL SELECT 'files', count(*) FROM documents_documentfile UNION ALL SELECT 'cabinets', count(*) FROM cabinets_cabinet UNION ALL SELECT 'tags', count(*) FROM tags_tag;"
实测回显:
t | count
-----------+-------
documents | 2
versions | 2
files | 2
cabinets | 1
tags | 1
(5 rows)
四、REST API 实战(curl 全链路)
API 根:/api/v4/(带 Token 访问返回 46 个端点分组)。下文 $TOKEN 即 §3.1 创建的 Token 值,$BASE=http://127.0.0.1:8140。
4.1 鉴权验证
curl -s -H "Authorization: Token $TOKEN" $BASE/api/v4/document_types/
实测回显节选(默认类型存在):
{
"count": 2,
"results": [
{"id": 1, "label": "Default", "trash_time_period": 30, ...},
{"id": 2, "label": "Contract", "filename_generator_backend": "uuid", ...}
]
}
无 Token 或 Token 错误返回 401。
4.2 建文档类型与抽屉
curl -s -X POST -H "Authorization: Token $TOKEN" -H "Content-Type: application/json" \
-d '{"label":"Contract","trash_time_period":30,"trash_time_unit":"days"}' \
$BASE/api/v4/document_types/
curl -s -X POST -H "Authorization: Token $TOKEN" -H "Content-Type: application/json" \
-d '{"label":"2026 Contracts","parent":null}' \
$BASE/api/v4/cabinets/
实测:两者均返回 201 与完整序列化对象(抽屉返回 full_path: "2026 Contracts")。
4.3 创建文档记录 + 上传文件(两步异步)
第一步:POST /documents/ 只建记录,不收文件。 文档记录(实测返回 id=3):
curl -s -X POST -H "Authorization: Token $TOKEN" -H "Content-Type: application/json" \
-d '{"label":"QZ-2026-0428 Purchase Contract","document_type_id":2,"description":"E2E OCR test with DejaVu font"}' \
$BASE/api/v4/documents/
第二步:向文档上传实际文件。 端点 POST /documents/{id}/files/,字段是 file_new(multipart),返回 202(后台受理):
curl -s -w '\nHTTP %{http_code}\n' -X POST -H "Authorization: Token $TOKEN" \
-F "file_new=@ocr-test2.png" -F "action_name=replace" -F "comment=clean font OCR test" \
$BASE/api/v4/documents/3/files/
实测回显:
HTTP 202
action_name=replace 表示新文件成为新的活动版本。上传后管线异步推进:文件落库 → 版本创建 → 页面拆分 → 预览图 → OCR → 索引(实测每步间隔 12~25 秒)。
4.4 读取版本页面与 OCR 结果
# 活动版本页面列表
curl -s -H "Authorization: Token $TOKEN" $BASE/api/v4/documents/3/versions/4/pages/
# 页面 OCR 内容(页面 id 由上一步返回)
curl -s -H "Authorization: Token $TOKEN" $BASE/api/v4/documents/3/versions/4/pages/4/ocr/
实测 OCR 回显:
{
"content": "Mayan EDMS OCR Test 2026\nPurchase Order Amount: 12345 USD\nContract Reference: QZ-2026-0428\n\nVendor: Quzuo Trading Co.\n"
}
与测试图原文逐行一致(Tesseract 5.5.0,英文 100% 命中)。
4.5 预览图渲染与文件下载
# 页面预览图
curl -s -o /dev/null -w 'image HTTP %{http_code} type=%{content_type} size=%{size_download}\n' \
-H "Authorization: Token $TOKEN" $BASE/api/v4/documents/3/versions/4/pages/4/image/
# 原文件下载(注意用文件 id,不是文档 id)
curl -s -o /dev/null -w 'download HTTP %{http_code} type=%{content_type} size=%{size_download}\n' \
-H "Authorization: Token $TOKEN" $BASE/api/v4/documents/3/files/4/download/
实测回显:
image HTTP 200 type=image/jpeg size=38118
download HTTP 200 type=image/png size=33338
下载字节数 33338 与上传原图完全一致(无损存取)。版本导出为异步动作:POST /documents/3/versions/4/export/ 返回 202,产物经导出队列落盘后再取。
4.6 挂抽屉与打标签
# 挂抽屉:面向抽屉的添加动作,字段名是 document(不是 document_id)
curl -s -w 'HTTP %{http_code}\n' -X POST -H "Authorization: Token $TOKEN" \
-H "Content-Type: application/json" -d '{"document": 3}' \
$BASE/api/v4/cabinets/1/documents/add/
# 打标签:先建标签,再挂到文档,字段名是 tag(不是 tag_id)
curl -s -X POST -H "Authorization: Token $TOKEN" -H "Content-Type: application/json" \
-d '{"label":"ocr-verified","color":"#2E86DE"}' $BASE/api/v4/tags/
curl -s -w 'HTTP %{http_code}\n' -X POST -H "Authorization: Token $TOKEN" \
-H "Content-Type: application/json" -d '{"tag": 1}' \
$BASE/api/v4/documents/3/tags/attach/
实测:挂抽屉返回 200;文档侧复核 GET /documents/3/cabinets/ 返回 count: 1 [('2026 Contracts', '2026 Contracts')],GET /documents/3/tags/ 返回 [('ocr-verified', '#2E86DE')]。
4.7 全文检索(中英实测)
检索端点形态是 GET /api/v4/search/<检索模型>/results 或 ?q=,检索模型名必须是 documents.documentsearchresult:
curl -s -H "Authorization: Token $TOKEN" \
"$BASE/api/v4/search/documents.documentsearchresult/?q=QZ-2026-0428"
实测回显节选:
{
"count": 1,
"results": [
{
"label": "QZ-2026-0428 Purchase Contract",
"document_type": {"id": 2, "label": "Contract", ...},
"file_latest": {"checksum": "02c622fb...", "comment": "clean font OCR test", ...}
}
]
}
中文检索同样命中(中文文档 language 设为 chi_sim 并重新识别后):
curl -s -H "Authorization: Token $TOKEN" \
"$BASE/api/v4/search/documents.documentsearchresult/?q=%E6%9B%B2%E4%BD%9C%E8%B4%B8%E6%98%93"
实测:count: 1,命中「QZ-2026-0429 中文采购合同」。
4.8 事件流与回收站
# 事件流(实测 46 条,含文档创建/版本提交/OCR 完成)
curl -s -H "Authorization: Token $TOKEN" "$BASE/api/v4/events/?page_size=3"
# 移入回收站与彻底清除(均异步 202)
curl -s -w 'HTTP %{http_code}\n' -X DELETE -H "Authorization: Token $TOKEN" $BASE/api/v4/documents/1/
curl -s -w 'HTTP %{http_code}\n' -X DELETE -H "Authorization: Token $TOKEN" $BASE/api/v4/trashed_documents/1/
实测回显:
HTTP 202
HTTP 202
4.9 API 字段名速查(踩坑总结)
| 想做的事 | 正确写法 | 错误写法(实测后果) |
|---|---|---|
| 上传文件 | POST /documents/{id}/files/,字段 file_new,返回 202 异步 | POST /documents/ 带 file 字段不报错但不建文件 |
| 挂抽屉 | POST /cabinets/{id}/documents/add/,body {"document": 3} | {"cabinet_id": 1} 打到 405;{"document_id": 3} 打到 400 |
| 打标签 | POST /documents/{id}/tags/attach/,body {"tag": 1} | {"tag_id": 1} 打到 400 "tag":["This field is required."] |
| 全文检索 | /search/documents.documentsearchresult/?q=... | /search/documents.search/... 打到 404 且应用日志堆栈报错 |
| 文档语言 | PATCH /documents/{id}/ body {"language":"chi_sim"} | 语言包装了但文档 language 仍是 eng 时 OCR 中文乱码 |
五、备份与恢复
5.1 备份对象盘点
默认部署共 5 个数据卷(docker volume ls 实测,卷名前缀即项目名):
| 卷 | 容量 | 内容 |
|---|---|---|
mayan-edms-412-stack_app | 828 KB | 文档文件存储 document_storage/、config.yml、预览缓存 |
mayan-edms-412-stack_postgres | 72.1 MB | 全部元数据 |
mayan-edms-412-stack_rabbitmq | 1.0 MB | 队列数据(可重建,价值低) |
mayan-edms-412-stack_redis | 4 KB | 锁/结果/事件流(可重建,价值低) |
mayan-edms-412-stack_postgres-initdb | — | 初始化脚本挂载点(空) |
必须备份的是前两个卷:文档二进制在 app 卷,结构化元数据在数据库卷,两者需同一时间点成对备份才能完整恢复。
5.2 备份实测
# ① 元数据库逻辑备份
docker compose exec postgresql pg_dump -U mayan mayan | gzip > mayan-db-20261028.sql.gz
# ② 应用数据卷打包(文档二进制 + config.yml)
docker run --rm -v mayan-edms-412-stack_app:/src:ro \
-v /opt/data/quzuo/tmp/mayan-edms/backup-drill:/backup alpine \
tar czf /backup/mayan-app-20261028.tgz -C /src .
实测产物:
mayan-db-20261028.sql.gz 58541 字节(zcat 首行:-- PostgreSQL database dump)
mayan-app-20261028.tgz 307046 字节
官方编排还内置了 postgresql-backup profile(pg_dump | gzip > /backups/$(date +%Y-%m-%d_%H-%M).sql.gz 写入专用备份卷),可按需启用做周期备份。
5.3 恢复要点
- 以同版本编排重建空栈(
up不启动应用),或先down清掉旧实例。 - 恢复数据库:
gunzip -c mayan-db-*.sql.gz | psql -U mayan mayan(空库导入)。 - 恢复应用卷:解包 tar 回
app卷(覆盖document_storage/与config.yml)。 - 启动后执行
common_perform_upgrade让迁移对齐版本,再核对search_status计数与文档下载完整性。
六、队列与进程观测
6.1 任务队列深度
docker compose exec rabbitmq rabbitmqctl list_queues -p mayan name messages
实测回显(空闲态,全部 0):
sources 0
file_metadata 0
documents_periodic 0
documents_file_slow 0
documents_file 0
default 0
workflows 0
converter 0
documents_exports 0
indexing_slow 0
search_slow 0
documents_slow 0
signatures_slow 0
events_fast 0
...(共 20+ 队列)
上传后持续不为 0 的队列即瓶颈点(对照六类 worker 的队列分工,见配置参数详解篇 §5.2)。
6.2 进程与日志
docker compose exec app supervisorctl status # 8 个进程 RUNNING 为健康态
docker compose logs app | grep -E 'ERROR|Traceback' | tail # 应用错误日志
实测:正常运维期日志仅出现少量中间件捕获的异常记录(对应 API 误用请求),worker 无异常。
七、排障实录汇编
7.1 检索端点模型名写错 → 404 + 日志堆栈
误用 /api/v4/search/documents.search/?q=... 返回 404 页面,应用日志出现 KeyError: 'documents.search' 堆栈(错误中间件捕获)。正确模型名用 GET /api/v4/search_models/ 查询,或直接用 documents.documentsearchresult。
7.2 API 字段名语义差异
挂抽屉/打标签的请求体字段不带 _id 后缀({"document": 3}、{"tag": 1}),带后缀会得到 400 校验错误;批量动作端点与单文档端点混用也会 404。第一次打不中时先看 400 回显里的字段提示。
7.3 上传后"文档没文件"
POST /documents/ 只建记录;文件必须走 POST /documents/{id}/files/(202 异步)。等待期间反复查询同一端点会得到 files count=0 的假象,管线完成后才出现文件与版本。
7.4 中文 OCR 乱码(两层根因)
①镜像默认语言包仅 eng/osd,需 MAYAN_APT_INSTALLS=tesseract-ocr-chi-sim 补包;②补包后仍乱码,因 OCR 语言取自文档 language 属性(默认 eng),PATCH 为 chi_sim 后重新提交 OCR 即全对。判定顺序:tesseract --list-langs → 文档 language → 重新提交识别。
7.5 删除文件连带版本页面消失
删除文档文件记录会级联清掉由它派生的版本页面(版本记录仍在、pages 归零、OCR 内容随页面消失)。清理重复文件前先核对 file_latest 与版本归属。
八、参考链接
- 官方文档站(4.12.2):https://docs.mayan-edms.com/
- REST API 概览与 OpenAPI Schema:
/api/v4/、/api/schema/(运行实例自带) - 官方源码仓库:https://gitlab.com/mayan-edms/mayan-edms
- 站内互链:《Mayan EDMS Docker Compose 部署实战》、《Mayan EDMS 配置参数详解》、《Mayan EDMS 介绍与选型指南》