Paperless-ngx 部署实战:PostgreSQL + Redis 文档库与固定公网访问

Paperless-ngx 部署实战:PostgreSQL + Redis 文档库与固定公网访问

前言

真正让纸质文件变麻烦的,往往不是数量本身,而是"以后还能不能找得到"。合同、发票、收据、扫描件和临时拍下来的照片一旦分散在文件夹、聊天记录和抽屉里,想回头定位某一份资料时,时间都耗在翻找上。Paperless-ngx 的思路正好相反:先把文档集中进一个自托管系统,再通过 OCR、标签、联系人和搜索把它们变成可以管理的数字档案。对我来说,这类系统最有价值的地方,不是演示页看起来多智能,而是上传之后能不能真的留下结构、以后能不能重新找到、服务出了问题能不能判断卡在哪一层。

这次我按实际部署链路来走,不把它包装成"上传以后什么都自动完成":先准备 PostgreSQL 和 Redis,用 Docker Compose 启动 Paperless-ngx、Tika 与 Gotenberg,确认 9981 页面能访问,再实际注册账号、上传文档、修改信息和新增联系人;本地流程跑通后,再用 cpolar 把 9981 提供到公网,并切换到固定二级子域名 paperless。数据库、任务队列、文档处理和远程入口会分开说明,哪些是项目能力、哪些是这篇实际验证到的结果,也尽量不混在一起。这样后续继续做 OCR、自动分类或更复杂工作流时,至少底座已经清楚。

1. Paperless-ngx 适合解决什么问题?

Paperless-ngx 是一个开源、自托管的文档管理系统,目标是把扫描件、PDF、图片等资料集中保存,再通过 OCR、标签、联系人、日期和搜索等方式整理。

它常见的能力包括:

  • OCR 识别扫描件和图片文字;
  • 标签和分类;
  • 全文搜索;
  • PDF、JPEG、PNG、TIFF 等格式处理;
  • consume folder 自动导入;
  • Web 页面管理;
  • 多用户和权限;
  • API、邮件、定时任务等自动化扩展;
  • 与 Tika、Gotenberg 等组件配合处理文档。

项目介绍部分还列出了:

  • 前端:Angular
  • 后端:Python + Django
  • OCR:Tesseract
  • Redis:任务队列与缓存
  • Apache Tika:内容提取
  • Gotenberg:PDF 渲染

数据库部分在这篇里存在两种口径:功能介绍中列出了 SQLite、PostgreSQL 和 MariaDB/MySQL,而后面的部署前提又明确写成"仅支持 PostgreSQL ≥ 12"。这次实际部署配置使用的是 PostgreSQL + Redis,所以后续操作全部按这条实际链路继续。

2. 部署前先确认资源和 Docker

这套方案给出的最低硬件要求是:

组件 要求
CPU 2 核以上(建议 4 核)
内存 ≥ 2 GB(建议 4 GB,尤其处理大量 PDF/OCR)
存储 至少 10 GB 可用空间
磁盘类型 SSD 推荐

Docker 和 Docker Compose 需要先准备好。

检查命令保持如下:

shell 复制代码
# 检查 Docker
docker --version        # ≥ 20.10

# 检查 Docker Compose
docker compose version   # ≥ v2.5(或 docker-compose ≥ 1.29)

网络方面,主机至少要能够在首次部署时拉取镜像;如果 PostgreSQL 或 Redis 不在同一套容器网络里,还要确保对应地址可以访问。

3. 这次数据库按 PostgreSQL 来准备

当前部署流程要求:

  • PostgreSQL ≥ 12
  • Redis 作为任务队列和缓存

Redis 可以使用 Compose 内的容器,也可以连接已有 Redis。

这次直接在 Compose 里启动 Redis,而 PostgreSQL 使用外部数据库。

4. 先创建 Paperless 数据库用户

进入 PostgreSQL 的 psql 命令行,并以 postgres 身份登录后,执行:

shell 复制代码
-- 1. 创建用户(角色)
CREATE USER paperless WITH LOGIN PASSWORD 'Sj***520!';

-- 2. 创建数据库(如果还没建)
CREATE DATABASE paperless OWNER paperless;

-- 3. (可选)授予权限
GRANT ALL PRIVILEGES ON DATABASE paperless TO paperless;

这里创建了:

  • 用户:paperless
  • 数据库:paperless
  • 数据库所有者:paperless

数据库账号最好单独创建,不直接使用 postgres 超级用户。这样权限范围更容易控制,后面排查数据库操作也更清楚。

这里还有一个非常需要留意的细节:上面的 SQL 密码写的是:

Sj***520!

而后面的 Compose 配置里 PAPERLESS_DBPASS 使用的是另一个字面值。数据库实际连接时,这两个位置必须与真实 PostgreSQL 用户密码保持一致,否则 Paperless-ngx 无法正常连接数据库。

5. 开始部署 Paperless-ngx

先确认 Docker:

shell 复制代码
docker --version

接着创建目录:

shell 复制代码
mkdir -p /docker/paperless
chmod -R 777 /paperless

这里创建的是:

/docker/paperless

但权限命令作用于:

/paperless

两个路径并不相同。真正执行权限修改前,先确认自己当前准备操作的目录,尤其 chmod -R 777 是递归权限操作,不适合在路径没核对时直接执行。

6. 创建 Docker Compose 配置

创建并编辑:

shell 复制代码
vi docker-compose.yml

Compose 内容如下:

shell 复制代码
version: "3.6"
services:
  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:2.19.6
    restart: unless-stopped
    ports:
      - "9981:8000"
    volumes:
      - ./data:/usr/src/paperless/data
      - ./media:/usr/src/paperless/media
      - ./export:/usr/src/paperless/export
      - ./consume:/usr/src/paperless/consume
    environment:
      # 改为指向内部 redis 容器
      PAPERLESS_REDIS: redis://:my_redis_password@redis:6379
      PAPERLESS_DBHOST: 192.168.42.140   # 数据库仍用外部
      PAPERLESS_DBUSER: paperless        # 输入刚建好的账号密码
      PAPERLESS_DBPASS: Sjixin520!
      PAPERLESS_DBNAME: paperless
      PAPERLESS_TIKA_ENABLED: 1
      PAPERLESS_TIKA_ENDPOINT: http://tika:9998
      PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: redis-server --requirepass my_redis_password
    # 如果需要持久化,可加 volume

  tika:
    image: apache/tika:latest
    restart: unless-stopped

  gotenberg:
    image: gotenberg/gotenberg:8.19
    restart: unless-stopped

这份配置包含四个服务:

Paperless-ngx Web

  • 镜像:ghcr.io/paperless-ngx/paperless-ngx:2.19.6
  • 外部端口:9981
  • 容器端口:8000
  • 数据目录:./data
  • 媒体目录:./media
  • 导出目录:./export
  • 导入目录:./consume

Redis

  • 镜像:redis:7-alpine
  • 密码:my_redis_password
  • 端口:6379

Tika

  • 镜像:apache/tika:latest
  • 服务地址:http://tika:9998

Gotenberg

  • 镜像:gotenberg/gotenberg:8.19
  • 服务地址:http://gotenberg:3000

PostgreSQL 使用外部地址:

192.168.42.140

数据库名和用户名都是:

paperless

配置里的密码字段是:

PAPERLESS_DBPASS: Sjixin520!

这里不要忽略前面数据库用户创建时使用的密码,两边真正运行时需要匹配。

7. 启动并先看日志

执行:

shell 复制代码
docker-compose up -d

然后查看 Web 服务日志:

shell 复制代码
docker logs -f paperless-webserver-1

日志正常以后,再访问:

http://IP:9981

能够看到 Paperless-ngx 页面,说明 Web 服务、容器和数据库等基础链路至少已经进入可用状态。

8. 注册账号并进入文档管理页面

第一次进入后先注册用户。

然后登录。

登录以后可以调整页面布局。

我更愿意先把界面和账号准备好,再开始传文档,因为后面真正要验证的是"文档进来以后能不能管理"。

9. 上传一份文档做实际验证

进入上传入口,添加文档。

上传完成后,打开文档详情。

页面里可以继续修改和编辑文档相关信息。

这一步至少确认了:

文件上传 → 文档进入 Paperless-ngx → 页面可打开 → 信息可编辑

而不是只停留在"首页能访问"。

10. 联系人和文档信息也可以继续管理

接着创建新的联系人。

页面还提供排序、显示和编辑等管理入口。

Paperless-ngx 的 OCR、自动分类、标签和全文搜索是它的重要功能方向,但这篇实际截图重点展示的是账号、上传、文档详情、联系人和页面管理,因此不把所有自动识别能力都写成已经逐项实测完成。

11. 本地文档库跑通以后,再处理公网访问

到这里,Paperless-ngx 已经可以在本地 9981 页面管理文档。

如果只在当前局域网中使用,到这里已经够用。

如果人在外面还需要查文档或维护资料,再给 Web 页面补公网入口更合理。

这里 cpolar 只负责:

把 Paperless-ngx 的 9981 Web 页面映射到公网。

PostgreSQL、Redis、OCR、Tika、Gotenberg 和文档本身仍然由原来的服务负责。

12. 安装 cpolar

执行安装命令:

shell 复制代码
sudo curl https://get.cpolar.sh | sh

安装完成后检查服务状态:

shell 复制代码
sudo systemctl status cpolar

服务正常以后,通过主机 IP + 9200 打开 cpolar Web 管理页面。

这里同时出现两种访问形式:

http://ip:9200

以及:

http://localhost:9200/

实际访问时,以当前设备真正可达的管理地址为准。

13. 先用随机域名验证 9981

进入【隧道管理 → 创建隧道】,配置为:

  • 隧道名称:paperless
  • 协议:http
  • 本地地址:9981
  • 域名类型:随机域名
  • 地区:China Top

创建完成以后,到在线隧道列表查看公网地址。

从其他设备访问。

Paperless-ngx 页面能够正常打开。

这一步确认的是:

本地 9981 → cpolar 随机公网地址 → 外部浏览器访问成功。

14. 长期使用,再换固定二级子域名

如果准备长期远程管理文档,固定地址更方便。

进入预留功能。

地区选择:

china Top

这次保留的名称是:

paperless

然后回到【隧道管理 → 隧道列表】,找到对应隧道并编辑。

修改为:

  • 域名类型:二级子域名
  • Sub Domain:填写已经保留的名称
  • 地区:China Top

点击更新。

更新以后,在线隧道列表中的地址会切换成固定二级子域名。

最后再用固定地址访问。

页面可以正常打开。

总结

Paperless-ngx 真正有价值的地方,不是"把纸扫描一下"这么简单,而是把零散文档变成一套长期可管理的档案系统:上传之后还能继续编辑、关联联系人、排序和查找,后面再逐步利用 OCR、标签和自动化能力扩展。

这次实际跑通的链路是:

PostgreSQL → Paperless 用户 / 数据库 → Docker Compose → Paperless-ngx 2.19.6 → Redis 7 → Tika → Gotenberg 8.19 → 9981 → 注册账号 → 上传文档 → 编辑文档 → 联系人 → cpolar → 随机公网地址 → 固定二级子域名 paperless

几个技术细节尤其值得记住:

  • PostgreSQL 用户:paperless
  • PostgreSQL 数据库:paperless
  • 外部数据库地址:192.168.42.140
  • Paperless-ngx 镜像:ghcr.io/paperless-ngx/paperless-ngx:2.19.6
  • Redis:redis:7-alpine
  • Tika:apache/tika:latest
  • Gotenberg:gotenberg/gotenberg:8.19
  • Web 端口:9981:8000
  • cpolar 管理端口:9200
  • 隧道名称:paperless
  • 固定二级子域名:paperless

我更倾向于把这套系统理解成"先把文档收进来,再逐步让它变得可检索、可分类、可远程管理"。这样比一上来就追求所谓"全自动智能归档"更稳,也更符合这次真正展示出来的使用结果。

相关推荐
天天喝旺仔10 小时前
Go 并发编程:Goroutine 与 Channel 实战
云原生·性能优化·架构·go
iNeuOS工业互联网1 天前
iNeuOS工业互联网操作系统,重要更新:性能优化、安全漏洞与BUG修复,远程控制响应效率大幅提升
性能优化·bug
Web3&Basketball2 天前
LLM 峰谷定价怎么吃满:一个能对账的错峰调度器
python·性能优化·大模型·任务调度·成本优化·deepseek·推理优化
yunwei372 天前
eBPF 教程:追踪 CUDA GPU 操作
linux·后端·性能优化
狼爷2 天前
磁盘IO打满怎么办?我用5个真实案例,总结了这套可复用的排查方法论
后端·性能优化
hhzz2 天前
【OpenCV 入门到精通 05】核心操作与像素处理:ROI、运算与性能优化
人工智能·python·opencv·性能优化
HwJack202 天前
HarmonyOS批量数据与性能优化实战:万条数据入库与不卡 UI 的查询
ui·性能优化·harmonyos
长征coder2 天前
【无标题】
java·性能优化
昇腾知识体系2 天前
昇腾 950 RegBase 性能优化:从 msprof 采数到优化手法
人工智能·华为·性能优化·知识图谱