用海外云服务器搭建 Paperless-ngx 文档管理系统(2026最新版)

📅 · ChengziCloud - 一站式云端服务

Meta Description: 手把手教你在海外云服务器上用 Docker Compose 搭建 Paperless-ngx 自建文档管理系统,实现扫描件 OCR 文字识别、全文检索、标签归档与多用户协作;含中文 OCR 配置、Nginx 反向代理 + Let's Encrypt SSL、数据备份与升级、性能调优与常见问题 FAQ,附 DigitalOcean / AWS Lightsail / 阿里云国际版 / 腾讯云国际版 服务器配置与价格对照表。

> 关键词:Paperless-ngx 部署、自建文档管理系统、OCR 全文检索、扫描件归档、Docker Compose 教程、海外云服务器、Nginx 反向代理、Let's Encrypt SSL、中文 OCR 识别、文档数字化

前言

家里成堆的纸质发票、保修单、体检报告、租房合同,手机相册里几千张随手拍下来的证件和收据——大多数人早就动过「把它们扫描存档」的念头,但真正动手时往往卡在同一个地方:存下来容易,找回来难。

把 PDF 丢进网盘,文件名靠手写,几个月后你想找「2025 年 11 月那笔设备采购的发票」,只能在几百个文件里一个个点开;把照片堆进相册,更是只能靠翻。真正好用的文档归档系统,必须解决三件事:把图片里的文字识别出来(OCR)、把这些文字建成可检索的索引、再用标签与日期把它们组织起来。

Paperless-ngx 正是为这个场景而生的自建软件。它是一个开源(GPL-3.0)的文档管理系统:你把 PDF、扫描件、照片往一个「投放目录」里一丢,它会自动 OCR、自动归类、自动建立全文索引,之后你就能像用搜索引擎一样,用发票号、公司名、合同条款里的任意一个词把文档捞出来。而且——所有文件都躺在你自己的服务器硬盘上,不上传任何第三方。

本文把搭建全过程拆成可以直接复制执行的命令,从选服务器、装 Docker、写 Compose、配中文 OCR,一路做到 Nginx 反代加 HTTPS、备份升级和性能调优,最后附上 12 条常见问题。即使你只会基本 Linux 操作,也能一次跑通。

> 💡 推荐部署方案:本文全部步骤都可在阿里云国际版 / AWS / 腾讯云国际版的海外轻量服务器上完成。通过 5.chengzicloud.cloud 购买海外云服务器,可享专属折扣与中文技术支持,同一台机器还能顺带跑博客、图床等其他自建服务。

一、先划边界:Paperless-ngx 与你已经在用的方案差在哪

站内已经写过很多「自建服务」,Paperless-ngx 很容易被误当成「又一个网盘」。它的前提条件和别人完全不同,这一节先把它和相邻方案切开,避免重复建设。

| 方案 | 回答的核心问题 | 前提条件 | 它不解决的问题 | |---|---|---|---| | Paperless-ngx | 扫描件里的字怎么搜得到 | 你要做「扫描到归档到检索」的文档流水线 | 不做多人实时协同编辑 | | Nextcloud | 文件怎么多端同步共享 | 你要一个私有网盘和共享文件夹 | 不做 OCR,也不做内容级检索 | | Meilisearch | 怎么给自己的应用加搜索 | 你要的是搜索引擎内核与 API | 它不是给人直接用的文档界面 | | MinIO | 海量文件存哪儿 | 你要一个 S3 兼容对象存储后端 | 不管理标签、日期、对应人等元数据 | | 第三方网盘 | 不想自己运维怎么存 | 你接受数据放在别人服务器上 | 隐私、数据主权、检索能力都不在你手里 |

一句话总结差异:Nextcloud 管的是「文件」,Paperless-ngx 管的是「文件里的信息」。 前者按文件名和目录组织,后者按内容和元数据组织。这也是为什么两者的部署可以并存——很多人把 Paperless 的 media 目录直接挂到 Nextcloud 或 MinIO 上,用前者检索、用后者同步和冷备。

二、Paperless-ngx 能做什么、又明确做不到什么

先给结论,再讲原理,避免你搭完才发现需求不匹配。

它擅长的事:

- OCR 文字识别:PDF、PNG、JPEG、TIFF、GIF、WebP 都会被识别并转成可检索的 PDF;开启 Tika 后还能吞下 Word、Excel、PowerPoint 及其 LibreOffice 对应的 .odt/.ods/.odp 等格式。 - 全文检索:用文档内容里的任意词搜索,支持按对应人(correspondent)、标签、文档类型、日期、存储路径多维筛选。 - 自动归类:可以设定规则,让来自某发件人或文件名含某关键词的文档自动打标签、自动归入某类。 - 多用户:支持多账号、权限分组、每用户独立的仪表盘视图。 - 原件永不修改:Paperless 会为每份文档保存校验和,并定期跑「sanity checker」核对原件有没有被动过;它只在旁边生成一份 PDF/A 归档副本用于浏览。 - 完全本地:没有云端依赖。它的 AI 附加功能(标签建议、文档问答)默认关闭,内置的标签/对应人建议用的是本地非大模型的小型机器学习模型,不会把你的文档发出去。

它明确做不到的事(反向边界,很重要):

- 不是协作文档平台:没有 Word 那样的实时协同编辑,别拿它替代在线 Office。 - 不重命名、不移动、不上传:它是一台「只读式归档机」,官方刻意不做文件管理动作——真要批量改文件名和标签,应该先用 beets/Picard 那类工具处理源文件,再丢进投放目录。 - 不支持按文件夹浏览:官方刻意只认标签和元数据,不提供「目录树」视图(这一点和 Nextcloud 恰好相反)。 - OCR 是有成本的:一张 A4 扫描件的识别要占用 CPU 和内存,批量导入几千页会很吃资源,低配机器上会明显变慢。

理解这条边界,你就知道该给它配什么服务器了:它不是 IO 密集型,也不是带宽密集型,而是「间歇性 CPU + 常驻内存」型负载。

三、服务器配置怎么选:配置与价格对照表

Paperless-ngx 用 Docker 部署时,默认会拉起五个容器:webserver(主程序)、db(PostgreSQL)、broker(Valkey 消息队列)、gotenberg(Office 转 PDF)、tika(Office 内容解析)。所以内存不能只按「一个网站」来算:

- 1C2G:能跑,但必须关掉 Tika/Gotenberg 并改用 SQLite,只适合单人、偶尔导入; - 2C4G:推荐起步档。完整五容器栈跑得稳,OCR 时响应也可接受; - 4C8G:适合多人共用、每天批量导入几百页扫描件; - 磁盘:这是最容易被低估的一项。文档是长期资产,原始件 + PDF/A 归档副本 + 缩略图会占掉约 2~3 倍原始体积,建议预留 100GB 以上,并单独挂载数据盘便于扩容和快照。

下面是主流海外厂商在 2026 年 10 月的公开价目(直接取自官方定价页),按「够用 / 推荐 / 宽裕」三档列出:

| 厂商与产品 | 规格(内存 / vCPU / SSD / 月流量) | 月费(USD) | 定位 | |---|---|---|---| | DigitalOcean Droplet | 1 GB / 1 vCPU / 25 GB / 1 TB | $6 | 轻量试用 | | DigitalOcean Droplet | 2 GB / 1 vCPU / 50 GB / 2 TB | $12 | 单人轻量 | | DigitalOcean Droplet | 4 GB / 2 vCPU / 80 GB / 4 TB | $24 | 推荐起步 | | DigitalOcean Droplet | 8 GB / 4 vCPU / 160 GB / 5 TB | $48 | 多人共用 | | DigitalOcean Droplet | 16 GB / 8 vCPU / 320 GB / 6 TB | $96 | 批量归档 | | AWS Lightsail | 1 GB / 2 vCPU / 40 GB / 2 TB | $7 | 轻量试用 | | AWS Lightsail | 2 GB / 2 vCPU / 60 GB / 3 TB | $12 | 单人轻量 | | AWS Lightsail | 4 GB / 2 vCPU / 80 GB / 4 TB | $24 | 推荐起步 | | AWS Lightsail | 8 GB / 2 vCPU / 160 GB / 5 TB | $44 | 多人共用 | | AWS Lightsail | 16 GB / 4 vCPU / 320 GB / 6 TB | $84 | 批量归档 | | 阿里云国际版 轻量/ECS | 2~4 GB / 1~2 vCPU | 约 $8 ~ $30 | 参考区间 | | 腾讯云国际版 轻量/CVM | 2~4 GB / 1~2 vCPU | 约 $8 ~ $28 | 参考区间 |

> 声明:本文价格数据采集于 2026 年 10 月,仅为公开官网参考区间(DigitalOcean 与 AWS Lightsail 为当日直读官价,阿里云国际版与腾讯云国际版因地域/活动差异仅给区间),实际价格以各厂商结算页为准,金额单位均为美元(USD),不含税费。选购时请以「内存 ≥ 4GB + 磁盘 ≥ 100GB」为首要判据。

> 💡 如果你还没有服务器,通过 5.chengzicloud.cloud 选购海外云服务器可享折扣;同一台 2C4G 机器除了跑 Paperless-ngx,还能余量跑一个博客或 Uptime Kuma 监控。

四、开工前准备:装好 Docker 与 Docker Compose

Paperless-ngx 官方推荐 Docker 路线,理由是升级维护最省心(官方明确说裸机安装「通常只适合进阶用户和贡献者」)。以下命令在 Ubuntu 22.04/24.04 和 Debian 12 上验证通用。

先用官方脚本安装 Docker Engine 与 Compose 插件,脚本会自动配置好 systemd 开机自启:

`bash // 更新系统并安装基础组件 sudo apt update && sudo apt upgrade -y sudo apt install -y curl ca-certificates gnupg

// 使用 Docker 官方一键脚本安装(含 compose 插件) curl -fsSL https://get.docker.com | sudo sh

// 当前用户加入 docker 组,免 sudo 执行 docker sudo usermod -aG docker $USER newgrp docker

// 验证版本 docker --version docker compose version `

接着打开防火墙,只放行 SSH 和 HTTP/HTTPS。主程序的 8000 端口不要对公网开放,它只给本机的 Nginx 反向代理用:

`bash // Ubuntu 使用 ufw sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable sudo ufw status `

`bash // CentOS / Rocky 使用 firewalld sudo firewall-cmd --permanent --add-service=ssh sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload `

最后给数据盘做准备。强烈建议把数据放在独立数据盘上(例如挂载到 /data),这样将来扩盘、做快照、迁移都不会动到系统盘:

`bash // 查看块设备,确认数据盘设备名(如 /dev/vdb) lsblk -f

// 假设数据盘为 /dev/vdb,格式化为 ext4 并挂载 sudo mkfs.ext4 /dev/vdb sudo mkdir -p /data echo '/dev/vdb /data ext4 defaults 0 2' | sudo tee -a /etc/fstab sudo mount -a df -h /data `

五、用 Docker Compose 部署 Paperless-ngx(完整步骤)

下面这条路线是官方推荐的「Docker Compose 模板」法:直接下载官方编排文件,只改必要的路径与密钥,可控且可升级。

第 1 步:建目录并下载官方编排文件。 我们把整个项目放在数据盘的 /data/paperless:

`bash sudo mkdir -p /data/paperless cd /data/paperless

// 下载「PostgreSQL + Tika」版本的编排文件(同时支持 Office 文档) sudo curl -fsSLO https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.postgres-tika.yml sudo curl -fsSLo docker-compose.env https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.env sudo curl -fsSLo .env https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/.env

// 重命名为 compose 默认读取的文件名,并建好投放与导出目录 sudo mv docker-compose.postgres-tika.yml docker-compose.yml mkdir -p consume export `

docker-compose.yml 里有三处需要你确认:数据库密码 POSTGRES_PASSWORD(默认是弱口令 paperless,必须改)、数据卷与宿主机目录的映射路径、以及端口映射。核心结构如下(其余服务保持默认即可):

`yaml services: broker: image: docker.io/valkey/valkey:9-alpine restart: unless-stopped volumes: - redisdata:/data db: image: docker.io/library/postgres:18 restart: unless-stopped volumes: - pgdata:/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 - gotenberg - tika ports: - "8000:8000" volumes: - data:/usr/src/paperless/data - media:/usr/src/paperless/media - ./export:/usr/src/paperless/export - ./consume:/usr/src/paperless/consume env_file: docker-compose.env environment: PAPERLESS_REDIS: redis://broker:6379 PAPERLESS_DBHOST: db PAPERLESS_DBENGINE: postgresql PAPERLESS_TIKA_ENABLED: 1 PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000 PAPERLESS_TIKA_ENDPOINT: http://tika:9998 gotenberg: image: docker.io/gotenberg/gotenberg:8.37 restart: unless-stopped command: - "gotenberg" - "--chromium-disable-javascript=true" - "--chromium-allow-list=file:///tmp/.*" tika: image: docker.io/apache/tika:3.3.1.0 restart: unless-stopped volumes: data: media: pgdata: redisdata: `

说明几点:broker 用的是 Valkey(Redis 改协议后社区分叉出来的开源版本),Paperless 只要求「兼容 Redis 协议」,所以你换成 Redis 甚至微软 Garnet 都可以;gotenberg 的启动参数里显式禁用了 Chromium 的 JavaScript,是为了让 .eml 邮件转 PDF 时不执行追踪像素和脚本;media 用命名卷保存文档,./consume 和 ./export 用宿主机目录方便你直接往里丢文件。

需要提醒的是,如果你打算把数据放在特定路径(比如独立数据盘 /data),不要改 compose 里容器内的路径,只改冒号左边:

`yaml volumes: - /data/paperless/consume:/usr/src/paperless/consume `

第 2 步:生成密钥并写配置。 docker-compose.env 里最关键的三个变量是访问地址、时区和密钥。先用官方给的方法生成一条随机密钥:

`bash // 生成一条 64 位随机密钥(官方文档推荐写法) python3 -c "import secrets; print(secrets.token_urlsafe(64))" `

然后把 docker-compose.env 改成像这样(把生成出来的随机串填进 PAPERLESS_SECRET_KEY):

`ini COMPOSE_PROJECT_NAME=paperless PAPERLESS_SECRET_KEY=把上面生成的随机串粘贴到这里 PAPERLESS_URL=https://paperless.example.com PAPERLESS_TIME_ZONE=Asia/Shanghai PAPERLESS_OCR_LANGUAGE=chi_sim PAPERLESS_OCR_LANGUAGES=chi_sim USERMAP_UID=1000 USERMAP_GID=1000 `

第 3 步:拉镜像并启动。 第一次会下载约几百 MB 的镜像,耐心等:

`bash cd /data/paperless sudo docker compose pull sudo docker compose up -d `

启动后用下面的命令确认五个容器都是 Up 状态:

`bash sudo docker compose ps `

此时在服务器本机上访问 http://127.0.0.1:8000 就应该能看到登录页。注意:8000 端口不要对公网开放,对外访问一律走后面的 Nginx 反代。

六、创建超级用户并登录

首次访问会引导你创建超级用户。如果命令行创建更顺手,也可以这样:

`bash // 交互式创建超级用户 sudo docker compose exec webserver python3 manage.py createsuperuser `

如果你希望在无人值守的部署(比如云厂商的自定义脚本、K8s)里自动建号,Paperless 支持用环境变量在首次启动时自动创建超管——在 docker-compose.env 里加两行即可:

`ini PAPERLESS_ADMIN_USER=admin PAPERLESS_ADMIN_PASSWORD=一条强密码 `

官方对此有一条重要提醒:超管拥有全部对象和文档的完全权限,日常使用建议另建一个普通账号,或者建完之后把超管「降级」成普通用户。更稳妥的做法是:超管只用来做维护,日常检索与上传用一个普通账号。

七、配置中文 OCR(最关键的一步,很多人在这里踩坑)

Paperless 的 OCR 依赖 OCRmyPDF + Tesseract。默认只装了英文(以及德、意、西、法五种语言),不做配置的话,你的中文扫描件识别出来就是一片空白。中文必须显式开两处:

`ini PAPERLESS_OCR_LANGUAGE=chi_sim PAPERLESS_OCR_LANGUAGES=chi_sim `

这两行的分工完全不同,别混:

- PAPERLESS_OCR_LANGUAGE 是「识别时用哪种语言模型」,默认值就是 eng; - PAPERLESS_OCR_LANGUAGES 是「额外安装哪些语言包」,默认什么都不装。

中文的两个坑要特别记住:第一,简体中文的代码是 chi_sim,必须用下划线,写成 chi-sim 会失效;第二,Tesseract 的 Debian 包名和语言代码并不总是一一对应,官方文档明确举例:繁体中文要写 chi_tra,但包名要写成 chi-tra。

改完后必须重建容器才会生效:

`bash cd /data/paperless sudo docker compose up -d --force-recreate webserver `

中英混排的文档可以写成 chi_sim+eng,但要知道代价:Tesseract 启用多种语言会显著增加 CPU 耗时,几百页的批量导入会明显变慢。翻译一下实践建议——中文文档为主就只留 chi_sim,确实有中英混排再考虑叠加。

顺便把几个影响日常体验、值得一次性调好的选项说一下(都写在 docker-compose.env 里):

| 变量 | 默认值 | 建议与说明 | |---|---|---| | PAPERLESS_OCR_MODE | auto | 有文本层的 PDF 自动跳过 OCR,混合文档集保留默认即可 | | PAPERLESS_OCR_OUTPUT_TYPE | pdfa | 生成 PDF/A 长期归档格式,适合需要长期保存的票据合同 | | PAPERLESS_OCR_CLEAN | clean | 用 unpaper 预处理提升识别率;改 clean-final 时不能与 redo 模式同用 | | PAPERLESS_OCR_DESKEW | true | 自动纠正扫描倾斜;与 redo 模式不兼容会自动关闭 | | PAPERLESS_OCR_ROTATE_PAGES | true | 自动纠正 90/180/270 度旋转,阈值默认 12 | | PAPERLESS_OCR_MAX_IMAGE_PIXELS | Pillow 默认 | 防止超大图片吃爆内存的安全上限,非必要不要调高 |

补充一个容易被忽略的细节:容器内跑 rootless 模式时,PAPERLESS_OCR_LANGUAGES 会失效(官方明确写了「此选项不得用于 rootless 容器」)。所以如果你打算用 user: 指令跑非 root 容器,就要提前把语言包打进自定义镜像,而不是靠这个变量。

八、投放目录与自动导入:把扫描件丢进去就自动归档

Paperless 的自动化核心是「投放目录(consume)」。你把文件复制进 consume 目录,后台的 consumer 进程会立刻发现、OCR、建立索引,然后把文件从 consume 里移走,在 media 里重新生成归档件。注意:文件是被「消费」掉的,不是留在原地——这一点和网盘完全不同。

几个能把效率拉满的开关(同样写在 docker-compose.env 里):

| 变量 | 默认值 | 用途 | |---|---|---| | PAPERLESS_CONSUMER_RECURSIVE | false | 是否递归扫描子目录,开启后子目录里的文件也会被消费 | | PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS | false | 把子目录名自动变成标签,必须同时开启 RECURSIVE | | PAPERLESS_CONSUMER_POLLING_INTERVAL | 关闭 | NFS 等不支持 inotify 的文件系统要靠它轮询发现新文件 | | PAPERLESS_CONSUMER_DELETE_DUPLICATES | false | 是否在消费阶段直接删除重复文件(见下方说明) | | PAPERLESS_CONSUMER_DISABLE | 未设置 | 设为任意值即彻底关闭投放目录监视,省资源 |

「子目录即标签」这一招特别好用:假设你按来源把扫描件分好类,consume/报税/2025/、consume/汽车/保养/,开启这两个开关后,落进 报税/2025/ 的文件会自动带上「报税」「2025」两个标签,落进 汽车/保养/ 的自动带上「汽车」「保养」。官方文档特别说明:这些分类目录不会被删除,所以你可以长期复用同一套目录结构,等于用一个文件夹体系自动喂标签。

如果你的数据盘是 NFS / 网络存储,一定要设 PAPERLESS_CONSUMER_POLLING_INTERVAL(例如 30),因为这类文件系统不支持 inotify 通知,默认配置下新文件根本不会被发现——这是官方文档明确点出的一个「不是 bug 的 bug」。

关于重复文件,v3 起行为变了:默认不再拒绝重复件,而是照常消费,并在界面上把它们标记出来(打开文档看「Duplicates」标签页,或在文档列表按「Duplicates」筛选即可集中处理)。如果你更想要老版本「发现重复就直接丢弃」的行为,把 PAPERLESS_CONSUMER_DELETE_DUPLICATES 设为 true 即可。

支持的格式方面:PDF、PNG、JPEG、TIFF、GIF、WebP 会被 OCR 后转成 PDF;纯文本直接原样收录;开启了 Tika 后,Word、Excel、PowerPoint 及 .odt/.ods/.odp 等 Office 文档也能吃下。有一个细节值得记住——Paperless 判断文件类型靠的是内容而不是扩展名,但通过投放目录进来的文件如果扩展名不被任何解析器支持,会被直接拒绝。

再强调一条反向边界:Paperless 不会帮你重命名、移动或上传文件(官方刻意不做,出于安全考虑)。所以正确的工作流是「在源头把文件名和目录理好 → 丢进投放目录 → 让 Paperless 接管归档与检索」,而不是指望它当文件管理器。

九、Nginx 反向代理 + Let's Encrypt 全站 HTTPS

对外提供服务必须套一层带 SSL 的反向代理,同时正确设置 PAPERLESS_URL(它一次性决定 ALLOWED_HOSTS、CORS_ALLOWED_HOSTS、CSRF_TRUSTED_ORIGINS 三个安全项)。先装 Nginx 与 Certbot:

`bash sudo apt install -y nginx certbot python3-certbot-nginx sudo systemctl enable --now nginx `

然后新建站点配置 /etc/nginx/conf.d/paperless.conf。下面是官方 Wiki 给出的 Paperless 专用配置,有三点不能省:上传体积上限(默认 1M 对扫描件太小)、WebSocket 升级头(否则界面数据不刷新)、以及登录页与其余路径分开的 Referrer-Policy(登录页需要 same-origin,否则 Django 的 CSRF 校验会拿到 null 而报错):

`nginx server { listen 80; server_name paperless.example.com;

client_max_body_size 10M;

location ~ ^/accounts/(signup|login|2fa)/ { proxy_pass http://127.0.0.1:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; proxy_set_header X-Forwarded-Proto $scheme; proxy_hide_header Referrer-Policy; add_header Referrer-Policy "same-origin" always; }

location / { proxy_pass http://127.0.0.1:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; 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-Host $server_name; proxy_set_header X-Forwarded-Proto $scheme; proxy_hide_header Referrer-Policy; add_header Referrer-Policy "no-referrer" always; } } `

上面 proxy_pass 里的 127.0.0.1:8000 只能在 Nginx 与容器同机时用;如果 Nginx 跑在宿主机而 Paperless 在 Docker 里,用 docker network inspect bridge 查到网桥地址(通常是 172.17.0.1:8000)替换它。检查配置并签发证书:

`bash sudo nginx -t sudo systemctl reload nginx sudo certbot --nginx -d paperless.example.com `

如果你还配了 Fail2ban 之类工具、需要按真实客户端 IP 来封禁,就要用到 PAPERLESS_TRUSTED_PROXIES。这里有一个已知的坑:Paperless 用 python-ipware 取真实 IP,它要求「受信代理的 IP」必须是 X-Forwarded-For 链表里的最后一项,而 Nginx 的 $proxy_add_x_forwarded_for 只会追加客户端 IP、不会带上 Nginx 自己的地址,于是日志里会出现 Unable to determine IP address。官方给出的修法是在头部末尾补一个固定 IP、并在环境变量里填同一个值(python-ipware 只做比对,填任意合法 IP 都行)。若你的场景不需要按真实 IP 封禁,可以暂时不配这一项。

十、数据备份、导出与版本升级

自建服务最怕的不是搭不起来,而是数据丢了。Paperless 有一个对备份极其友好的设计:你的文档是以普通文件形式躺在 media 目录里的,随时可以拖出来用别的系统打开。而且官方说明——Paperless 从不修改你的原始文档,它会保存每份文件的校验和,并定期跑一个「健全性检查器」核对原件有没有被动过。

所以需要备份的东西一共四块:

| 备份对象 | 内容 | 方式 | |---|---|---| | media | 原始文档 + PDF/A 归档 + 缩略图 | 打包卷目录或直接 rsync | | data | 搜索索引、分类模型、SQLite 库 | 打包卷目录 | | 数据库 | PostgreSQL 里的元数据(标签、日期、对应人) | pg_dump 导出 SQL | | 配置 | docker-compose.yml / docker-compose.env / .env | 一起复制走即可 |

一个可直接照抄的备份脚本思路是「先停服保证一致性,再打包 + 导出,最后启回来」:

`bash cd /data/paperless

// 停止容器,确保数据库与文件一致 sudo docker compose stop

// 导出数据库(PostgreSQL 版) sudo docker compose start db sudo docker compose exec -T db pg_dump -U paperless paperless > /data/backup-db.sql

// 打包媒体与数据卷(卷名取决于 .env 里的 COMPOSE_PROJECT_NAME) sudo tar czf /data/backup-media-$(date +%F).tar.gz \ -C /var/lib/docker/volumes/paperless_media . sudo tar czf /data/backup-data-$(date +%F).tar.gz \ -C /var/lib/docker/volumes/paperless_data .

// 三个配置文件也一起备份 sudo cp docker-compose.yml docker-compose.env .env /data/

// 全部停止,备份完再整体启动 sudo docker compose stop sudo docker compose up -d `

如果你只是想把文档导出成人类可读的文件名(默认是按内部 ID 命名的),官方提供了一个专门的导出命令,配合 PAPERLESS_FILENAME_FORMAT 可以重排出「对应人/日期/标题」这样的目录结构:

`bash // 把全部文档导出到 ./export,文件名按配置格式生成 sudo docker compose exec webserver document_exporter ../export `

关于卷目录,有一点务必记住:Docker 命名卷在 Linux 上的默认位置是 /var/lib/docker/volumes/<项目名>_media/_data。这个目录只能用于备份,不要手工改权限、也不要手工搬文件——它完全由 Docker 和 Paperless 托管,人工干预极易损坏索引与文件的对应关系。

升级很简单,官方推荐两条命令:先 docker compose pull 拉新镜像,再 docker compose up -d 重建容器。但要划一条红线:Paperless-ngx 从 v2 升到 v3 有专门的破坏性变更和升级步骤,必须先读官方的 v3 迁移指南再动手,不能直接 pull 覆盖。另外,如果你是从更早的 Paperless-ng / 原版 Paperless / LinuxServer.io 镜像迁移过来,官方文档里都有对应的逐步迁移说明(其中一条常见坑是需要跑一次 document_index reindex 来为老文档重建搜索索引,之后索引会自动维护)。

十一、安全加固:别让「隐私自建」变成「裸奔公网」

很多人自建的初衷就是数据主权,结果却把服务裸奔在公网上。按优先级做完下面几条,风险就能压到很低:

- 主程序端口不对公网开放。8000 只给本机 Nginx 用;对外只放行 80/443 与你的 SSH 端口。 - PAPERLESS_SECRET_KEY 必须是随机长串,不能留 change-me。官方警告:这个值用于会话令牌与签名,设置不当会让第三方伪造认证凭据;同时它也要求唯一——重复用同一个密钥相当于给攻击者留了万能钥匙。 - 超管只用于维护。日常检索和上传用普通账号,避免超管权限被滥用。 - 开启双因素认证。Paperless 内置了 TOTP 两步验证,并提供了独立的两步验证页面(这也是为什么 Nginx 配置里要单独为 /accounts/(signup|login|2fa)/ 分组处理)。 - 套 HTTPS 并强制跳转。用 Certbot 签发的证书,并把 80 端口 301 到 443。 - 部署 Fail2ban。套在 Nginx 认证日志上,自动封禁暴力破解来源。 - 保持系统与镜像更新。定期 apt upgrade,并把镜像拉取与升级纳入每月例行。

十二、性能调优:让 OCR 不再拖慢整机

Paperless 的性能瓶颈几乎永远在 OCR,而不是在磁盘或网络。所以调优的目标是「把 CPU 用在对的地方,别把内存撑爆」。核心旋钮有三个:

| 变量 | 默认值 | 说明 | |---|---|---| | PAPERLESS_TASK_WORKERS | 1 | 后台并行处理的任务数;核多可适当调高,但每个 worker 都吃内存 | | PAPERLESS_THREADS_PER_WORKER | 按核数 | 单个任务内部用于 OCR 的线程数,调高能加速单份大文档 | | PAPERLESS_WEBSERVER_WORKERS | 1 | 前端进程数;调高前端更快,但每个进程都独立载入应用、更吃内存 |

如果你用的是低配机器(比如 1C2G 或树莓派),官方给了一整套「省资源」处方,实测有效:

- 改用 SQLite 而非 PostgreSQL,省下一整个数据库容器的内存; - 如果不用投放目录,直接 PAPERLESS_CONSUMER_DISABLE 关掉消费者; - 设 PAPERLESS_OCR_PAGES=1,只对第一页做 OCR——大多数文档第一页的信息就足以被检索到; - 设 PAPERLESS_ARCHIVE_FILE_GENERATION=never,完全不生成 PDF/A 归档,省磁盘(代价是不能在浏览器里看 PDF/A 视图); - 设 PAPERLESS_OCR_CLEAN=none,跳过 unpaper 预处理,OCR 更快更省内存(代价是识别率略降); - 把 PAPERLESS_WEBSERVER_WORKERS 压到 1。

最有性价比的一条其实是在扫描端就把 OCR 做掉。不少扫描仪自带 OCR,如果你的设备支持,让它先识别,Paperless 就能直接复用文本层、跳过最耗 CPU 的那一步——这一点在官方文档里被明确推荐,尤其对树莓派这类低功耗设备。

十三、常见问题 FAQ

Q1:中文扫描件识别出来全是空白或乱码,怎么办?

99% 是中文语言包没装。中文要同时设置 PAPERLESS_OCR_LANGUAGE=chi_sim(用哪种语言模型)和 PAPERLESS_OCR_LANGUAGES=chi_sim(额外安装哪个语言包),改完必须 docker compose up -d --force-recreate webserver 重建容器。注意简体中文是 chi_sim,必须用下划线,写成 chi-sim 会失效。

Q2:往投放目录里丢了文件,但系统一点反应都没有?

先分三种情况排查。一是文件系统用了 NFS,它不支持 inotify 文件通知,必须设 PAPERLESS_CONSUMER_POLLING_INTERVAL 开启轮询。二是文件在子目录里而没开递归,需要 PAPERLESS_CONSUMER_RECURSIVE=true。三是 consumer 进程没起来,用 docker compose ps 看容器状态、docker compose logs webserver 看日志。

Q3:文档被「消费」之后,原文件去哪了?

被移走了。Paperless 会把投放目录里的文件消费掉,在 media 里重新生成归档件——投放目录不会留着原文件。所以千万别把唯一的原件直接丢进去,应保留一份自己的原始来源目录。

Q4:重复的文件会被自动拒绝吗?

v3 起默认不拒绝,而是照常消费并在界面标出重复(文档的「Duplicates」标签页,或按「Duplicates」筛选集中查看)。想恢复老版本「直接丢弃重复件」的行为,把 PAPERLESS_CONSUMER_DELETE_DUPLICATES=true 即可。

Q5:最低配置能跑在 1C2G 上吗?

能,但要降级:关掉 Tika/Gotenberg(放弃 Office 文档支持)、改用 SQLite、把 PAPERLESS_OCR_PAGES=1。体验最好还是 2C4G + 100GB 磁盘起步,OCR 时才不会把整机拖死。

Q6:它会把我的文档传到云端或者喂给 AI 吗?

不会,除非你主动开启。Paperless 的 AI 功能(文档问答、LLM 辅助)默认关闭;内置的标签/对应人建议用的是本地非大模型的小型机器学习模型,不上传数据。只有你显式启用并配置了 LLM 后端(可以指向本地 Ollama),文档内容才会发给那个后端。

Q7:支持 Word、Excel、PPT 吗?

支持,但要启用 Tika 集成(本文用的 postgres-tika 编排文件已包含 Tika 与 Gotenberg 两个服务)。启用后 .docx/.doc/.odt/.ppt/.pptx/.odp/.xls/.xlsx/.ods 都能收录;不启用时只有 PDF、图片、纯文本。

Q8:备份到底要备哪几样?

四块:media 卷(文档本体)、data 卷(索引与模型)、PostgreSQL 的 pg_dump 导出、以及三个配置文件。建议脚本化并直接同步到异地或对象存储。

Q9:升级会不会丢数据?

常规升级不会,官方流程就是 docker compose pull 加 docker compose up -d。唯一要警惕的是大版本升级:v2 升 v3 有专门的破坏性变更与迁移步骤,必须先读官方 v3 迁移指南。升级前照例先备份。

Q10:能不能直接用 IP 访问,不配域名?

技术上可以(改 compose 的端口映射后用 http://IP:8000),但强烈不建议:没有 HTTPS 意味着登录凭据明文传输。正确做法是配一个域名、套 Nginx 反代签证书、并把 PAPERLESS_URL 设成该 HTTPS 地址。

Q11:能让它自动收取邮箱里的发票附件吗?

可以,Paperless 支持邮件收取(incoming mail),能直接连 IMAP 拉取附件并归档,也支持 OAuth 与 GPG 加密邮件。这是把「邮箱里的电子发票」自动归档的好办法,配合规则打标签几乎零维护。

Q12:CentOS 7 上能装吗?

Docker 镜像本身能跑,Paperless 全容器化,所以 CentOS 7 偏低的内核/glibc 版本不是障碍——真正的障碍是 CentOS 7 已经停止维护,以及需要手动补装 Docker Compose v2 插件。新机器建议直接用 Ubuntu 22.04/24.04 或 Debian 12,少踩一堆系统层的坑。

Q13:上传大文件报错怎么办?

两个地方都要放行:Nginx 的 client_max_body_size(本文已设为 10M,可按需调大),以及确认反向代理没有超时截断。固定 IP 的服务器一般不需要额外调整。

Q14:端口 8000 被占用了怎么改?

改 docker-compose.yml 里的端口映射,只改冒号左边,例如 - "8010:8000",容器内永远还是 8000。改完 docker compose up -d 重建即可。

结语

Paperless-ngx 的价值不在于「又多了个能存文件的地方」,而在于它把一堆死掉的扫描件变成了可检索、可追溯、可长期保存的数字资产。整套搭建的难点其实只有三个:给够内存和磁盘、把中文 OCR 的两个变量配对(chi_sim + chi_sim)、以及前置一层带 HTTPS 的 Nginx。剩下的,交给它的自动消费流水线就行。

如果你还在纠结服务器选哪家,记住本文的核心判据:内存 ≥ 4GB、磁盘 ≥ 100GB、放在海外(访问稳定且不折腾备案)。按这个标准选出的一台 2C4G,就能把上述整套系统稳稳跑起来。

> 💡 通过 5.chengzicloud.cloud 购买阿里云国际版 / AWS / 腾讯云国际版海外服务器,可享专属折扣,一台机器同时承载文档系统、博客与监控服务,性价比更高。

延伸阅读:

- Nextcloud 私有云盘部署教程:文件同步与共享 - MinIO 自建 S3 对象存储部署教程 - Meilisearch 自建搜索服务部署教程 - Docker + Portainer 容器可视化管理平台部署 - Nginx 反向代理 + Let's Encrypt SSL 完整配置教程 - 服务器备份与灾难恢复实战指南

> 本文由 5.chengzicloud.cloud 提供,点击访问首页了解更多海外云服务器部署方案和专属优惠。