跳转到内容

Paperless-ngx:纸质文档归档 ​

完成后,把扫描仪或手机拍的纸质文档丢进一个共享文件夹,Paperless-ngx 会自动做 OCR(包括中文)、归档、打标签,之后可以全文搜索。你也清楚数据库和文档该怎么备份。

适合谁 ​

  • 有一堆合同、发票、账单、证件要整理,希望搜得到。
  • 有扫描仪,或者愿意用手机扫描 App 把文件传到 NAS 的共享文件夹里。
  • 能接受它吃 CPU:OCR 很耗资源,官方有专门的低配设备章节。

应用信息 ​

项内容
示例清单有 paperless-ngx,示例文件日期 2026-03-30,缺少 v3 必填的两个变量,见下
容器broker(Redis)、db(PostgreSQL)、webserver(Paperless-ngx)
示例里的端口8000(示例注释里写的是 8010,以 ports 的实际值为准)
数据文档原件和归档版本在 media;搜索索引在 data;导出放在 export;投递目录 consume
官方文档docs.paperless-ngx.com

示例没有 v3 要求的两个变量

Paperless-ngx 现在的最新发布是 v3.x,而示例的镜像用 latest。官方的 v3 迁移指南明确:

  • PAPERLESS_SECRET_KEY 变成必填项,用于签名,应该是一个很长的随机值。
  • PostgreSQL 必须显式写 PAPERLESS_DBENGINE: postgresql。v3 不再根据 PAPERLESS_DBHOST 推断数据库类型。

示例里两者都没有。没有密钥,官方文档说 Paperless 会拒绝启动;没有 PAPERLESS_DBENGINE,数据库类型默认是 sqlite,示例里那个 PostgreSQL 容器就白跑了。下面的版本补上了这两项。示例里的数据库密码 paperless 也是默认值,建议换掉。

部署 ​

准备这些共享文件夹,名字自己取:

共享文件夹用途
appdataRedis、PostgreSQL 的数据,Paperless 的 data。放在 SSD 上更快
paperless文档原件 media 和导出目录 export。放大盘
scans投递目录,扫描仪和手机用 SMB 往里放文件。需要给扫描用的用户写权限,见常见权限方案

专用用户 appuser 对它们有读写权限,见容器权限:PUID、PGID 与共享文件夹。

服务 → Compose → 文件(Services → Compose → Files)→ 添加 → 从模板添加,选 paperless-ngx,添加后 编辑。改成这样:

yaml
services:
  broker:
    image: docker.io/library/redis:8
    restart: unless-stopped
    volumes:
      - ${{ sf:"appdata" }}/paperless-ngx/redis:/data
  db:
    image: docker.io/library/postgres:17
    restart: unless-stopped
    volumes:
      - ${{ sf:"appdata" }}/paperless-ngx/postgres:/var/lib/postgresql
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: <数据库密码>
  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    restart: unless-stopped
    depends_on:
      - db
      - broker
    ports:
      - "8000:8000"
    volumes:
      - ${{ sf:"appdata" }}/paperless-ngx/data:/usr/src/paperless/data
      - ${{ sf:"paperless" }}/media:/usr/src/paperless/media
      - ${{ sf:"paperless" }}/export:/usr/src/paperless/export
      - ${{ sf:"scans" }}:/usr/src/paperless/consume
    environment:
      PAPERLESS_REDIS: redis://broker:6379
      PAPERLESS_DBHOST: db
      PAPERLESS_DBENGINE: postgresql
      PAPERLESS_DBPASS: <数据库密码>
      PAPERLESS_SECRET_KEY: <随机密钥>
      PAPERLESS_TIME_ZONE: ${{ tz }}
      PAPERLESS_OCR_LANGUAGE: chi_sim+eng
      PAPERLESS_OCR_LANGUAGES: chi-sim
      USERMAP_UID: ${{ uid:"appuser" }}
      USERMAP_GID: ${{ gid:"users" }}

改动的说明:

  • <数据库密码> 要在 db 和 webserver 里写成同一个值,不然连不上数据库。compose 文件默认只有 root 能读。
  • <随机密钥> 用官方的办法生成:在你的电脑或 OMV 的 shell 里运行 python3 -c "import secrets; print(secrets.token_urlsafe(64))"。
  • PostgreSQL 版本:示例用 17,官方当前的 compose 用 18。新装两个都可以,装好之后别改大版本:PostgreSQL 大版本之间的数据目录不兼容,Paperless 的官方做法是先备份,再用导出和导入配合新建的数据库,见官方文档的 Database Upgrades 一节。
  • PAPERLESS_OCR_LANGUAGES 是要安装的语言包,空格分隔,这里写 chi-sim;PAPERLESS_OCR_LANGUAGE 是识别时使用的语言,用 Tesseract 的三位代码,名字里的 - 要写成 _,所以是 chi_sim,多个语言用 + 连接。繁体中文是 chi-tra 和 chi_tra。语言越多,CPU 耗得越多。 另外官方说明,指定了额外语言就不能用 rootless 容器。
  • USERMAP_UID、USERMAP_GID 决定 Paperless 用哪个用户读写投递目录,要对上 appuser 和 users。
  • 通过反向代理用域名访问时,还要设 PAPERLESS_URL,见反向代理与 HTTPS。
  • 示例的 .env 文件里有一处拼写错误(APERLESS_REDIS),不影响,因为上面的 environment 里已经写了 PAPERLESS_REDIS。

点 保存,检查,上线。第一次要下载镜像,数据库和索引初始化也要一会儿。

首次使用 ​

  1. 浏览器打开 http://<NAS 的 IP>:8000。官方文档说,第一次打开网页会提示创建超级用户。没有出现提示的话,在 OMV 的 shell 里(root)运行 omv-compose-run paperless-ngx exec webserver createsuperuser,按提示创建。
  2. 超级用户拥有所有文档的权限,官方建议再建一个日常使用的普通账号。
  3. 把一个 PDF 放进 scans 共享文件夹,等一会儿,它会从投递目录消失,出现在 Paperless 里。处理完的文件会被移走,所以别把唯一的一份原件直接放进投递目录。

投递目录在 NFS 这类不支持 inotify 的网络文件系统上时,新文件不会被发现,要设 PAPERLESS_CONSUMER_POLLING_INTERVAL 为一个正数来启用轮询。scans 是 NAS 本地的共享文件夹,不受影响。

备份:数据库和文档怎么备份才安全 ​

别指望不停机的热备份

Paperless 把文档的元数据、标签、对应关系都放在 PostgreSQL 里。数据库文件在写入时被复制,拷贝可能损坏。

  • 影响范围:数据库坏了,文档原件还在,但标签、通信方、自定义字段这些整理工作全部丢失,要重新整理。
  • 前置条件:不要给它的计划备份勾选 跳过容器停止 / 启动,见更新与备份容器。
  • 怎么回退:已经热备份过的,当作不可靠,按下面的方式补做一份导出。

官方给的应用自带的备份是 文档导出器(document_exporter):它把所有文档、缩略图、数据库里的全部元数据导出到一个目录,里面有 manifest.json。

sh
omv-compose-run paperless-ngx exec -T webserver document_exporter ../export
  • 这条命令在 OMV 的 shell 里以 root 运行。-T 不分配终端,用在定时任务里不会报错。../export 是容器里的路径,它对应你挂载的 paperless/export。
  • 目标目录里已有内容时,它只更新有变化的文件,不会删除已有的文件。想把已删除文档对应的文件也清掉,加 -d,目标目录里有别的文件时要小心。
  • 把这条命令放进 系统 → 计划任务(System → Scheduled Tasks),每天夜里跑一次,见计划任务。
  • 官方提醒备份前最好确认没有在导入文档。

然后把这些东西用文件备份工具备份到别处,见rsync 任务:

内容位置
导出目录paperless/export
文档原件paperless/media
compose 文件插件的计划备份会带上

要点:

  • 导出只能被同版本的 Paperless-ngx 导入。 官方说:导出里是数据库的一个精确镜像,迁移可能改变表结构,所以不同版本之间导入可能失败。恢复时,装一个和导出时相同版本的全新实例。
  • 导出不含 API 令牌,恢复后要重新生成。
  • 导入器应该在一个完全空的 Paperless-ngx 上运行,用 document_importer,具体步骤按官方的管理文档,别凭记忆敲命令。
  • 不用导出器的方案是直接备份 Docker 卷或目录,数据库也要一起,并且要先停容器。这就是插件默认的「停止 → 备份 → 启动」,但注意插件默认只备份 1 GB 以内的卷,media 要加 # BACKUP 或用文件备份工具。

升级 ​

  • v3 有破坏性改动。 官方的迁移指南说,升级到 v3 只能从 2.20.15 开始,并且有一批变量要改:消费者的轮询变量改名、重复文档默认不再拒绝、OCR 模式的取值变了、搜索索引会重建、预处理脚本不再收到位置参数等。升级前读完迁移指南。
  • 升级前先停容器,做一次备份(导出加停机备份)。
  • 官方说明镜像可以固定到一个发布系列,写成 3.3 这类系列标签,只升补丁版本,不跨系列自动升级。把数字换成你当前的系列。latest 永远指向最新稳定版。
  • 手动更新:拉取、上线,见更新与备份容器。别放进计划自动更新。

检查结果 ​

  1. 在 OMV 的 shell 里(root)运行 omv-compose-run paperless-ngx ps,broker、db、webserver 都在运行。
  2. http://<NAS 的 IP>:8000 能登录。
  3. 在 SMB 客户端往 scans 放一个含中文的扫描件,几分钟内出现在 Paperless 里,搜索其中的中文词能搜到。
  4. 手动运行一次导出命令,paperless/export 里出现 manifest.json。
  5. 重启 NAS,应用自己回来了。

常见问题 ​

容器起不来,日志提到 SECRET_KEY 或者数据库连接。 先查是不是缺了 PAPERLESS_SECRET_KEY 或 PAPERLESS_DBENGINE;再看两处数据库密码是否一致。

投递目录里的文件没动静。 检查 USERMAP_UID、USERMAP_GID 对上了目录的属主,扫描仪写进来的文件是否还在被写入,再看日志。

中文识别不出来。 没安装语言包,或者没设识别语言。两个变量都要设,改完下线再上线重建容器,装语言包需要联网。

导入文档时 CPU 一直满载。 OCR 本来就耗 CPU,多语言更耗。大量导入时放在夜里做。

导入后提示重复文档。 v3 默认允许重复,只是标出来。要拒绝重复,设 PAPERLESS_CONSUMER_DELETE_DUPLICATES=true。

参考资料 ​

OpenMediaVault 非官方中文使用指南,与 openmediavault 项目及其开发者无隶属关系。