一、项目概述
Paperless-ngx 是一个文档管理系统,旨在将你的物理文档转换为可搜索的在线归档,让你真正做到"少纸化"(Paperless)。作为原 Paperless 和 Paperless-ng 项目的官方继任者,paperless-ngx 由社区团队共同维护,提供了更强大的功能和更活跃的社区支持。
核心特性:
- 自动化文档处理:通过 OCR(光学字符识别)自动提取文档文本内容
- 智能搜索:基于 Tantivy 的全文搜索引擎,支持复杂的查询语法
- 文档分类与标签:支持自定义标签、文档类型和 Correspondent(发件人)管理
- 多格式支持:支持 PDF、图片(JPG、PNG、TIFF 等)、Office 文档等多种格式
- REST API:完整的 RESTful API,方便与其他系统集成
- 现代化前端:基于 Angular 构建的响应式 Web 界面
- Docker 部署:提供官方 Docker 镜像,支持一键部署
- 多语言支持:通过 Crowdin 协调,支持多种语言翻译
适用场景:
- 个人文档数字化归档(发票、合同、证件等)
- 家庭文档管理(保险单、医疗记录、税务文件)
- 小型办公室文档管理系统
- 需要自托管解决方案的隐私敏感用户
二、技术原理
2.1 架构设计
Paperless-ngx 采用经典的前后端分离架构:
┌─────────────────────────────────────────┐
│ 前端 (Angular) │
│ - 文档上传、浏览、搜索、管理界面 │
│ - 基于 TypeScript + Angular 17+ │
└─────────────────┬───────────────────────┘
│ REST API
┌─────────────────▼───────────────────────┐
│ 后端 (Django + DRF) │
│ - 文档处理流水线 │
│ - OCR 识别与文本提取 │
│ - 全文搜索 (Tantivy) │
│ - 用户认证与权限管理 │
└─────────────────┬───────────────────────┘
│
┌─────────────────▼───────────────────────┐
│ 任务队列 (Celery) │
│ - 异步文档处理任务 │
│ - 定时任务(文档消费、邮件检查等) │
│ - 使用 Redis 作为消息代理 │
└─────────────────┬───────────────────────┘
│
┌─────────────────▼───────────────────────┐
│ 存储层 (PostgreSQL/MySQL/SQLite) │
│ - 元数据、标签、分类等信息 │
│ - 文档原始文件存储 (media 目录) │
└─────────────────────────────────────────┘
2.2 核心技术栈与选型理由
后端技术栈:
- Python 3.11+:现代化的 Python 版本,性能提升显著
- Django 5.2+:成熟的 Web 框架,提供 ORM、认证、管理后台等基础设施
- Django REST Framework:构建 RESTful API 的标准选择
- Celery:处理异步任务(文档处理、邮件检查等),支持分布式部署
- Redis:作为 Celery 的消息代理和结果后端,同时用于缓存
- PostgreSQL/MySQL:生产环境推荐使用,支持完整的文本搜索特性
前端技术栈:
- Angular 17+:企业级前端框架,TypeScript 原生支持
- Angular Material:UI 组件库,提供一致的视觉体验
- NgRx(可选):状态管理,适用于复杂的交互逻辑
文档处理技术:
- OCRmyPDF:基于 Tesseract 的 OCR 引擎,支持多语言识别
- PyMuPDF (fitz):高性能的 PDF 处理库
- pdf2image:将 PDF 转换为图像,用于预览和 OCR 预处理
- Tantivy:用 Rust 编写的全文搜索引擎库,性能优异
为什么选择这些技术?
- Django + DRF:快速开发,生态成熟,自带管理后台
- Celery:解耦耗时任务,提升用户体验
- Tantivy:比 Elasticsearch 更轻量,比 SQLite FTS 性能更好
- Docker:简化部署,确保环境一致性
2.3 关键算法与设计模式
文档处理流水线:
# 简化的文档处理流程(基于源码逻辑)
class DocumentProcessor:
def process_document(self, document_id):
# 1. 消费文件(从 consume 目录或上传)
file_path = self.consume_file(document_id)
# 2. OCR 识别与文本提取
text = self.extract_text(file_path)
# 3. 生成缩略图
self.generate_thumbnail(file_path)
# 4. 自动匹配规则(Correspondent、类型、标签)
self.apply_matching_rules(document_id, text)
# 5. 创建搜索索引
self.update_search_index(document_id, text)
# 6. 保存元数据到数据库
self.save_metadata(document_id)
全文搜索实现:
Paperless-ngx 使用 Tantivy 作为搜索引擎,核心代码在 src/documents/search.py:
# 创建搜索索引
def add_or_update_document(document):
writer = get_search_writer()
writer.add_document(
id=str(document.id),
title=document.title,
content=document.content,
# 存储用于过滤的字段
correspondent=document.correspondent.name if document.correspondent else "",
tags=" ".join(tag.name for tag in document.tags.all()),
)
writer.commit()
异步任务设计:
使用 Celery 处理耗时操作,避免阻塞 Web 请求:
@app.task
def consume_file_task(file_path, override_filename=None):
"""消费上传的文件并创建文档"""
# 文件消费逻辑
document = consume_file(file_path, override_filename)
# 触发异步处理
if document:
consume_file_task.apply_async(args=[document.id], countdown=5)
2.4 数据流分析
文档上传与处理流程:
- 用户通过 Web 界面或 API 上传文档(支持拖拽、多选)
- 后端接收文件,保存到
consume目录(或直接处理) - Celery 任务被触发,开始处理文档:
- 检测文件类型(PDF、图片、Office 文档)
- 如果是 PDF,检查是否已有文本层(避免重复 OCR)
- 调用 OCRmyPDF 进行 OCR 识别
- 提取元数据(创建时间、作者等)
- 生成缩略图(小、中、大三种尺寸)
- 文档元数据保存到数据库
- 文档内容被索引到 Tantivy
- 用户可以在界面上搜索和浏览文档
搜索流程:
- 用户在搜索框输入查询(支持高级语法,如
tag:invoice date:2024-01) - 后端解析查询,转换为 Tantivy 查询语句
- Tantivy 执行搜索,返回匹配的文档 ID
- 后端从数据库加载完整元数据
- 前端渲染搜索结果,高亮匹配的文本片段
三、安装与快速开始
3.1 环境要求
最低配置:
- CPU:1 核
- 内存:2 GB RAM
- 存储:根据文档数量,建议 10 GB 以上
- 操作系统:Linux、macOS、Windows(通过 Docker)
推荐配置:
- CPU:2 核以上
- 内存:4 GB RAM 以上
- 存储:SSD 硬盘
3.2 Docker Compose 安装(推荐)
这是最简单的安装方式,适合大多数用户。
Step 1: 下载 docker-compose.yml
# 创建项目目录
mkdir -p ~/paperless-ngx
cd ~/paperless-ngx
# 下载官方 docker-compose.yml
curl -O https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.postgres.yml
curl -O https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/compose.env
Step 2: 配置环境变量
编辑 compose.env,修改以下配置:
# 数据库配置(默认即可)
PAPERLESS_DBENGINE=postgresql
PAPERLESS_DBNAME=paperless
PAPERLESS_DBUSER=paperless
PAPERLESS_DBPASS=paperless
# 时区设置(重要!)
PAPERLESS_TIME_ZONE=Asia/Shanghai
# 可选:设置管理员账号
PAPERLESS_ADMIN_USER=admin
PAPERLESS_ADMIN_PASSWORD=your_secure_password
# 可选:启用 OCR 语言包(默认只有英文)
PAPERLESS_OCR_LANGUAGE=eng+chi_sim+chi_tra
Step 3: 启动服务
docker compose -f docker-compose.postgres.yml up -d
Step 4: 访问 Web 界面
打开浏览器,访问 http://localhost:8000,使用设置的管理员账号登录。
3.3 一键安装脚本
Paperless-ngx 提供了交互式安装脚本:
bash -c "$(curl -L https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/install-paperless-ngx.sh)"
脚本会引导你完成:
- 选择安装目录
- 配置端口
- 选择数据库(PostgreSQL 或 MariaDB)
- 配置时区和语言
3.4 最简运行示例
使用默认配置快速启动(SQLite 数据库):
# 下载简化版 docker-compose.yml
curl -O https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.sqlite.yml
# 启动服务
docker compose -f docker-compose.sqlite.yml up -d
# 查看日志
docker compose -f docker-compose.sqlite.yml logs -f
上传第一个文档:
# 方法 1:通过 Web 界面上传
# 访问 http://localhost:8000,点击"上传"按钮
# 方法 2:通过 consume 目录(适合批量导入)
# 将文件复制到容器的 consume 目录
docker cp my_document.pdf paperless-ngx-web:/usr/src/paperless/consume/
四、使用方法与实战
4.1 基础用法
1. 文档上传
- Web 界面上传:支持拖拽、多选,可以批量上传
- 邮件导入:配置 IMAP 邮箱,自动拉取邮件附件
- Consume 目录:将文件放入
consume目录,自动导入 - API 上传:通过 REST API 集成到其他系统
2. 文档搜索
Paperless-ngx 提供强大的搜索功能:
- 基础搜索:输入关键词,搜索标题和内容
- 高级搜索语法:
tag:发票- 搜索标签为"发票"的文档correspondent:电力公司- 搜索发件人为"电力公司"的文档type:合同- 搜索指定文档类型date:2024-01- 搜索 2024 年 1 月的文档is:not_tagged- 搜索未打标签的文档content:水电费- 搜索内容包含"水电费"的文档
3. 自动化规则
在"设置"→“匹配规则"中配置自动化规则,例如:
- 如果发件人是"XX 电力”,自动添加标签"水电费"
- 如果文件名包含"发票",自动设置为"发票"类型
- 如果内容包含"合同",自动添加到"合同"对应人
4.2 进阶用法
1. 集成 Scanner(扫描仪)
如果你有支持网络扫描的扫描仪,可以配置 SMB/NFS 共享,让扫描仪直接扫描到 consume 目录。
2. 使用 API 自动化
Paperless-ngx 提供完整的 REST API,可以通过 API Token 进行认证:
# 获取 API Token(在用户设置中生成)
# 上传文档
curl -X POST http://localhost:8000/api/documents/post_document/ \
-H "Authorization: Token YOUR_TOKEN" \
-F "document=@/path/to/document.pdf" \
-F "title=我的文档" \
-F "correspondent=1" \
-F "tags=1,2,3"
3. 配置 Nginx 反向代理
在生产环境中,建议使用 Nginx 作为反向代理:
server {
listen 80;
server_name paperless.example.com;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
4. 数据备份
定期备份数据库和文档文件:
# 备份脚本示例
#!/bin/bash
BACKUP_DIR=/path/to/backup
DATE=$(date +%Y%m%d)
# 备份 PostgreSQL 数据库
docker exec paperless-ngx-db pg_dump -U paperless paperless > $BACKUP_DIR/db_$DATE.sql
# 备份文档文件
tar -czf $BACKUP_DIR/media_$DATE.tar.gz /path/to/paperless/media
# 备份配置文件
tar -czf $BACKUP_DIR/config_$DATE.tar.gz /path/to/paperless/compose.env
4.3 实际项目示例
场景:家庭文档管理系统
需求:
- 管理家庭的水电费、物业费等账单
- 归档保险单、医疗记录等重要文件
- 支持多用户(家庭成员)访问
实施步骤:
- 部署 Paperless-ngx:使用 Docker Compose 部署,配置 PostgreSQL
- 配置匹配规则:
- 发件人包含"电力公司" → 标签"水电费"
- 发件人包含"物业" → 标签"物业费"
- 文件名包含"保险" → 类型"保险单"
- 设置定期备份:使用 cron 定时执行备份脚本
- 配置邮件导入:设置 IMAP 邮箱,自动导入账单邮件的附件
- 创建家庭成员账号:为每个家庭成员创建账号,设置合适的权限
五、常见问题与解决方案
5.1 安装失败
问题:Docker 镜像拉取失败
错误信息:Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled
解决方案:
- 配置 Docker 镜像加速器(如使用腾讯云、阿里云镜像加速)
- 检查网络连接,确保可以访问 Docker Hub
- 尝试手动拉取镜像:
docker pull ghcr.io/paperless-ngx/paperless-ngx:latest
问题:PostgreSQL 无法启动
错误信息:FATAL: password authentication failed for user "paperless"
解决方案:
- 检查
compose.env中的数据库密码配置 - 确保 PostgreSQL 容器和 Web 容器使用相同的环境变量文件
- 删除卷并重新创建:
docker compose down -v && docker compose up -d
5.2 运行时错误
问题:OCR 识别失败
错误信息:ERROR: Failed to OCR document
可能原因:
- 内存不足(OCR 需要较多内存)
- 文档格式不支持
- Tesseract 语言包未安装
解决方案:
- 增加 Docker 容器的内存限制
- 检查文档格式,确保是支持的格式(PDF、图片)
- 在
compose.env中配置PAPERLESS_OCR_LANGUAGE,安装所需语言包
问题:搜索结果不准确
可能原因:
- Tantivy 索引未正确更新
- 文档内容未正确提取
解决方案:
# 重建搜索索引
docker exec -it paperless-ngx-web python3 manage.py document_index reindex
5.3 性能问题
问题:文档处理速度慢
解决方案:
- 启用 GPU 加速(需要配置 CUDA 和相应的 Docker 镜像)
- 增加 Celery worker 数量:在
docker-compose.yml中设置PAPERLESS_TASK_WORKERS=4 - 使用更快的存储(SSD)
- 限制同时处理的文档数量
问题:Web 界面加载慢
解决方案:
- 配置 Nginx 缓存
- 启用 Gzip 压缩
- 使用 CDN 加速静态资源
5.4 兼容性问题
问题:某些 PDF 无法处理
可能原因:
- PDF 加密或密码保护
- PDF 版本过旧或过新
- 损坏的 PDF 文件
解决方案:
- 使用工具(如 qpdf)移除密码保护:
qpdf --password=PASSWORD --decrypt input.pdf output.pdf - 尝试将 PDF 转换为图像,再重新生成 PDF
- 检查 PDF 是否损坏:
pdfinfo input.pdf
问题:中文 OCR 识别率低
解决方案:
- 确保安装了中文语言包:
PAPERLESS_OCR_LANGUAGE=chi_sim+chi_tra+eng - 提高 OCR 精度:设置
PAPERLESS_OCR_MODE=force(强制 OCR,即使已有文本层) - 使用更高质量的扫描图像(300 DPI 以上)
六、总结
Paperless-ngx 是一个功能强大、社区活跃的开源文档管理系统,非常适合个人和小团队使用。其核心价值在于:
- 完整的文档处理流水线:从上传到 OCR 识别、索引、搜索,一气呵成
- 现代化的技术栈:Django + Angular + Tantivy,性能和可维护性兼顾
- 灵活的部署方式:Docker、裸机、云端,随心选择
- 强大的搜索能力:基于 Tantivy 的全文搜索,支持复杂查询
- 活跃的社区:作为 Paperless-ng 的官方继任者,拥有持续的维护和丰富的文档
不足之处:
- 对硬件资源有一定要求(尤其是 OCR 处理)
- 移动端界面体验一般(正在改进中)
- 高级功能(如工作流、自动化)相对简单
未来展望:
根据 GitHub 路线图和社区讨论,Paperless-ngx 未来可能加入:
- 更强大的自动化工作流引擎
- AI 辅助的文档分类和实体提取
- 改进的移动端体验
- 支持更多文档格式(如 EML、MSG)
推荐理由:
如果你正在寻找一个自托管的文档管理解决方案,Paperless-ngx 绝对值得尝试。它不仅能帮你摆脱纸质文档的困扰,还能通过数字化和智能化手段,让你的文档管理更加高效、有序。
资源链接:
- 官方文档:https://docs.paperless-ngx.com/
- GitHub 仓库:https://github.com/paperless-ngx/paperless-ngx
- Docker Hub:https://hub.docker.com/r/paperlessngx/paperless-ngx
- 社区论坛:https://github.com/paperless-ngx/paperless-ngx/discussions
- Matrix 聊天室:https://matrix.to/#/#paperless:matrix.org
希望这篇指南能帮助你快速上手 Paperless-ngx。如果你有任何问题或建议,欢迎在评论区留言!