这是一份面向新 Ubuntu VPS / 服务器的 Paperless-ngx 手动部署笔记,目标是用 Docker Compose 搭建一套可迁移、可备份、中文 OCR 不容易在升级后丢失的文档管理系统。适合 1Panel 用户,也适合直接用命令行管理 Docker Compose 的场景。
一、参考资料
- 官方项目仓库:paperless-ngx/paperless-ngx
- 官方安装文档:Setup – Paperless-ngx
- 官方配置文档:Configuration – Paperless-ngx
- Docker Hub 镜像:paperlessngx/paperless-ngx
二、部署架构

本方案使用 3 个核心容器:
paperless-ngx:Web 页面、任务处理、OCR、文档管理主程序。paperless-ngx-db:PostgreSQL 数据库,保存文档元数据、用户、标签、分类规则等。paperless-ngx-broker:Valkey/Redis 队列服务,用于异步任务。
新部署建议直接使用 PostgreSQL,不建议继续用 SQLite。PostgreSQL 更适合长期保存、备份和迁移,也更适合后续扩展。
三、端口和目录规划
下面是一套可直接套用的规划,实际部署时按你的 VPS IP、域名和目录习惯调整即可。
| 项目 | 示例值 | 说明 |
|---|---|---|
| 部署目录 | /opt/1panel/docker/compose/paperless-ngx |
放在 1Panel 常用 compose 目录下,方便面板查看 |
| Web 端口 | 36070 |
宿主机访问端口 |
| 容器端口 | 8000 |
Paperless-ngx 默认端口 |
| 访问地址 | http://YOUR_VPS_IP:36070 |
替换成你的 VPS IP 或域名 |
| OCR 语言 | chi_sim+chi_tra+eng |
简体中文、繁体中文、英文 |
| 时区 | Asia/Shanghai |
中国时区 |
四、目录结构建议

建议在部署目录下创建这些子目录:
data/:索引、分类模型等应用数据。media/:上传后的原始文件、归档文件、缩略图等,是最重要的数据目录。consume/:自动消费目录,把 PDF、图片等放进去会被 Paperless 自动导入。export/:导出和迁移使用。pgdata/:PostgreSQL 数据库文件。redisdata/:Valkey/Redis 数据。tessdata/:中文 OCR 语言包,建议持久化,升级容器后不容易丢。
五、部署流程总览

六、安装或检查 Docker
先确认系统已有 Docker 和 Docker Compose:
<code class="language-bash">docker --version docker compose version</code>
如果没有 Docker,可以用官方方式安装,或在 1Panel 里安装 Docker 环境。安装后确认当前用户是否有权限执行 Docker;没有权限时就用 sudo docker ...。
七、创建部署目录
<code class="language-bash">sudo mkdir -p /opt/1panel/docker/compose/paperless-ngx cd /opt/1panel/docker/compose/paperless-ngx sudo mkdir -p data media export consume pgdata redisdata tessdata sudo chown -R 1000:1000 data media export consume redisdata tessdata</code>
如果你的 Docker 容器使用的 UID/GID 不是 1000:1000,先查宿主机用户 ID:
<code class="language-bash">id -u id -g</code>
然后把后文的 USERMAP_UID、USERMAP_GID 改成对应值。
八、生成随机密码和 Secret Key
新 VPS 不要直接复制别人的密码,建议现场生成:
<code class="language-bash">openssl rand -base64 32 openssl rand -base64 48</code>
也可以用 Python 生成 Secret Key:
<code class="language-bash">python3 -c "import secrets; print(secrets.token_urlsafe(64))"</code>
至少准备 3 个值:
- 数据库密码:填入
PAPERLESS_DBPASS - Paperless Secret Key:填入
PAPERLESS_SECRET_KEY - 初始管理员密码:填入
PAPERLESS_ADMIN_PASSWORD
九、编写 docker-compose.yml
在部署目录创建 docker-compose.yml:
<code class="language-yaml">name: paperless-ngx
services:
broker:
image: docker.io/valkey/valkey:8-alpine
container_name: paperless-ngx-broker
restart: unless-stopped
volumes:
- ./redisdata:/data
db:
image: docker.io/library/postgres:16-alpine
container_name: paperless-ngx-db
restart: unless-stopped
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: ${PAPERLESS_DBPASS}
volumes:
- ./pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U paperless -d paperless"]
interval: 10s
timeout: 5s
retries: 10
webserver:
image: docker.io/paperlessngx/paperless-ngx:latest
container_name: paperless-ngx
restart: unless-stopped
depends_on:
db:
condition: service_healthy
broker:
condition: service_started
ports:
- "36070:8000"
env_file: docker-compose.env
volumes:
- ./data:/usr/src/paperless/data
- ./media:/usr/src/paperless/media
- ./export:/usr/src/paperless/export
- ./consume:/usr/src/paperless/consume
- ./tessdata/chi_sim.traineddata:/usr/share/tesseract-ocr/5/tessdata/chi_sim.traineddata:ro
- ./tessdata/chi_tra.traineddata:/usr/share/tesseract-ocr/5/tessdata/chi_tra.traineddata:ro</code>
这里把宿主机端口设置为 36070,容器内仍然使用 Paperless-ngx 默认的 8000。镜像也可以换成 ghcr.io/paperless-ngx/paperless-ngx:latest;如果 VPS 拉 GitHub Container Registry 慢或失败,Docker Hub 镜像通常更顺手。
数据库镜像用 postgres:16-alpine 是一个稳妥选择。不要随意升级 PostgreSQL 主版本,数据库主版本升级不是简单换镜像。
十、编写 docker-compose.env
在同一目录创建 docker-compose.env:
<code class="language-env">PAPERLESS_REDIS=redis://broker:6379
PAPERLESS_DBHOST=db
PAPERLESS_DBNAME=paperless
PAPERLESS_DBUSER=paperless
PAPERLESS_DBPASS=CHANGE_ME_DB_PASSWORD
PAPERLESS_SECRET_KEY=CHANGE_ME_SECRET_KEY
PAPERLESS_URL=http://YOUR_VPS_IP:36070
PAPERLESS_ALLOWED_HOSTS=YOUR_VPS_IP,localhost,127.0.0.1
PAPERLESS_CSRF_TRUSTED_ORIGINS=http://YOUR_VPS_IP:36070
PAPERLESS_TIME_ZONE=Asia/Shanghai
PAPERLESS_OCR_LANGUAGE=chi_sim+chi_tra+eng
PAPERLESS_FILENAME_FORMAT={{ created_year }}/{{ correspondent }}/{{ title }}
PAPERLESS_CONSUMER_POLLING=60
PAPERLESS_TASK_WORKERS=1
PAPERLESS_THREADS_PER_WORKER=2
PAPERLESS_ADMIN_USER=admin
PAPERLESS_ADMIN_PASSWORD=CHANGE_ME_ADMIN_PASSWORD
PAPERLESS_ADMIN_MAIL=admin@localhost
USERMAP_UID=1000
USERMAP_GID=1000</code>
必须替换这些占位符:
CHANGE_ME_DB_PASSWORDCHANGE_ME_SECRET_KEYCHANGE_ME_ADMIN_PASSWORDYOUR_VPS_IP
如果使用域名和 HTTPS 反向代理,建议改成:
<code class="language-env">PAPERLESS_URL=https://paperless.example.com PAPERLESS_ALLOWED_HOSTS=paperless.example.com,localhost,127.0.0.1 PAPERLESS_CSRF_TRUSTED_ORIGINS=https://paperless.example.com</code>
注意 URL 后面不要加 /。
十一、中文 OCR 的两种处理方式
Paperless-ngx 里有两个很像但含义不同的配置:
PAPERLESS_OCR_LANGUAGE=chi_sim+chi_tra+eng:告诉 Paperless 实际 OCR 时使用哪些语言。PAPERLESS_OCR_LANGUAGES=chi-sim chi-tra:Docker 启动时额外安装哪些 Tesseract 语言包。
注意下划线和短横线的区别:使用语言是 chi_sim、chi_tra,安装包名是 chi-sim、chi-tra。
方案 A:让容器启动时自动安装
如果新 VPS 网络正常、容器能访问 Debian apt 源,可以在 docker-compose.env 里加:
<code class="language-env">PAPERLESS_OCR_LANGUAGES=chi-sim chi-tra PAPERLESS_OCR_LANGUAGE=chi_sim+chi_tra+eng</code>
首次启动会慢一些,因为容器要安装中文 OCR 包。缺点是网络、代理或 apt 源不稳定时,容器可能启动失败或一直 unhealthy。
方案 B:把中文 traineddata 持久化挂载
更推荐长期使用这个方案:把 chi_sim.traineddata、chi_tra.traineddata 放进宿主机 ./tessdata/,再通过 compose 单文件挂载到容器内。
如果容器能临时启动,可以先进入容器安装:
<code class="language-bash">docker exec -it paperless-ngx bash apt-get update apt-get install -y tesseract-ocr-chi-sim tesseract-ocr-chi-tra tesseract --list-langs exit</code>
然后复制语言包到宿主机:
<code class="language-bash">cd /opt/1panel/docker/compose/paperless-ngx docker cp paperless-ngx:/usr/share/tesseract-ocr/5/tessdata/chi_sim.traineddata ./tessdata/chi_sim.traineddata docker cp paperless-ngx:/usr/share/tesseract-ocr/5/tessdata/chi_tra.traineddata ./tessdata/chi_tra.traineddata sudo chown 1000:1000 ./tessdata/*.traineddata</code>
确认 docker-compose.yml 中有这两行挂载:
<code class="language-yaml"> - ./tessdata/chi_sim.traineddata:/usr/share/tesseract-ocr/5/tessdata/chi_sim.traineddata:ro
- ./tessdata/chi_tra.traineddata:/usr/share/tesseract-ocr/5/tessdata/chi_tra.traineddata:ro</code>
之后可以不再使用 PAPERLESS_OCR_LANGUAGES,只保留:
<code class="language-env">PAPERLESS_OCR_LANGUAGE=chi_sim+chi_tra+eng</code>
十二、启动服务
先检查 compose 配置:
<code class="language-bash">cd /opt/1panel/docker/compose/paperless-ngx docker compose --env-file docker-compose.env config --quiet</code>
拉取镜像并启动:
<code class="language-bash">docker compose --env-file docker-compose.env pull docker compose --env-file docker-compose.env up -d</code>
查看状态:
<code class="language-bash">docker ps --format "table {{.Names}}t{{.Status}}t{{.Ports}}"</code>
正常情况下应该看到 paperless-ngx 和 paperless-ngx-db 都是 healthy,paperless-ngx-broker 为 Up,Web 端口映射类似 0.0.0.0:36070->8000/tcp。
十三、验证 OCR 和中文界面
检查日志:
<code class="language-bash">docker logs --since 5m paperless-ngx</code>
正常日志中不应出现 chi_sim not installed、chi_tra not installed、SystemCheckError。
检查 Tesseract 语言:
<code class="language-bash">docker exec paperless-ngx tesseract --list-langs</code>
应该至少包含:
<code class="language-text">chi_sim chi_tra eng</code>
访问页面:
<code class="language-text">http://YOUR_VPS_IP:36070</code>
网页语言通常跟随浏览器或用户语言设置。想显示简体中文,优先把浏览器语言设为简体中文,或登录后在用户/前端偏好里选择中文。不建议靠 LANG=zh_CN.UTF-8、LC_ALL=zh_CN.UTF-8 强行设置容器语言,有些官方镜像里没有这个 locale,会出现 setlocale 警告。
十四、1Panel 管理方式
如果想让 1Panel 统一管理:
- 把部署目录放到
/opt/1panel/docker/compose/paperless-ngx。 - 在该目录保留
docker-compose.yml和docker-compose.env。 - 用命令启动后,1Panel 的容器列表一般可以看到这 3 个容器。
- 如果 1Panel 的编排页面没有自动识别,可以在面板里手动添加已有 compose 项目,或继续用命令行管理。
不要在 1Panel 面板里随意重建数据库容器并清空挂载目录。pgdata/ 和 media/ 是最重要的数据。
十五、反向代理和公网访问
如果只在局域网访问,用 http://IP:36070 即可。公网访问建议使用 HTTPS 反向代理,并让这几项保持一致:
<code class="language-env">PAPERLESS_URL=https://paperless.example.com PAPERLESS_ALLOWED_HOSTS=paperless.example.com,localhost,127.0.0.1 PAPERLESS_CSRF_TRUSTED_ORIGINS=https://paperless.example.com</code>
反代时重点检查:
- 上传文件大小限制要调高,否则大 PDF 上传会失败。
- 代理超时不要太短,避免大文件上传或 OCR 处理时中断。
- 反代域名、
PAPERLESS_URL、PAPERLESS_CSRF_TRUSTED_ORIGINS必须一致。 - Paperless 保存的通常是敏感文档,公网暴露前务必启用 HTTPS、强密码、备份和访问控制。
十六、日常使用
上传文件有两种常用方式:
- 网页上传:打开 Web 页面直接上传。
- 自动消费目录:把文件放到宿主机
consume/目录。
如果 consume/ 在 NFS、SMB、NAS 挂载目录上,文件系统通知可能不可靠,建议保留:
<code class="language-env">PAPERLESS_CONSUMER_POLLING=60</code>
这会让 Paperless 每 60 秒主动扫描一次消费目录。
十七、备份和迁移
最少要备份这些内容:
<code class="language-text">/opt/1panel/docker/compose/paperless-ngx/docker-compose.yml /opt/1panel/docker/compose/paperless-ngx/docker-compose.env /opt/1panel/docker/compose/paperless-ngx/data/ /opt/1panel/docker/compose/paperless-ngx/media/ /opt/1panel/docker/compose/paperless-ngx/pgdata/ /opt/1panel/docker/compose/paperless-ngx/tessdata/</code>
建议也备份:
<code class="language-text">/opt/1panel/docker/compose/paperless-ngx/export/ /opt/1panel/docker/compose/paperless-ngx/consume/</code>
官方提供 document_exporter,可以导出文档、缩略图和元数据:
<code class="language-bash">cd /opt/1panel/docker/compose/paperless-ngx docker compose exec -T webserver document_exporter ../export</code>
这个导出适合迁移或做额外保险,但不要把它当成唯一备份。数据库目录、媒体目录和配置文件仍建议直接备份。
十八、升级方法
升级前先备份:
<code class="language-bash">cd /opt/1panel/docker/compose/paperless-ngx docker compose down tar -czf paperless-ngx-backup-$(date +%F).tar.gz docker-compose.yml docker-compose.env data media pgdata tessdata docker compose up -d</code>
确认备份后再升级:
<code class="language-bash">cd /opt/1panel/docker/compose/paperless-ngx docker compose --env-file docker-compose.env pull docker compose --env-file docker-compose.env up -d docker logs --since 5m paperless-ngx</code>
升级时要特别注意:
- 不要随意升级 PostgreSQL 主版本,例如从 16 直接改 18。
- 如果没有持久化
tessdata/,升级或重建容器后中文 OCR 语言包可能丢失。 latest会跟随最新稳定版。如果想更保守,可以固定 Paperless 主版本标签。- 升级后先检查
docker ps是否 healthy,再上传测试文档验证 OCR。
十九、常见故障排查
容器 unhealthy
<code class="language-bash">docker logs --tail 200 paperless-ngx docker logs --tail 100 paperless-ngx-db</code>
常见原因包括数据库没起来、docker-compose.env 拼写错误、PAPERLESS_SECRET_KEY 未设置或太短、OCR 语言包缺失导致系统检查失败。
日志提示 chi_sim 或 chi_tra not installed
这说明你设置了:
<code class="language-env">PAPERLESS_OCR_LANGUAGE=chi_sim+chi_tra+eng</code>
但容器里没有对应 Tesseract 语言包。处理方式二选一:加上自动安装配置:
<code class="language-env">PAPERLESS_OCR_LANGUAGES=chi-sim chi-tra</code>
或者把 chi_sim.traineddata、chi_tra.traineddata 持久化挂载到容器的 Tesseract tessdata 目录。
日志出现 locale 警告
如果看到类似:
<code class="language-text">setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8): No such file or directory</code>
通常是因为给容器设置了 LANG=zh_CN.UTF-8 或 LC_ALL=zh_CN.UTF-8。删除这两项即可,网页简体中文不靠这两个变量控制。
登录、上传或反代时报 403 CSRF
检查这三项是否和实际访问地址一致:
<code class="language-env">PAPERLESS_URL= PAPERLESS_ALLOWED_HOSTS= PAPERLESS_CSRF_TRUSTED_ORIGINS=</code>
如果访问地址是 https://paperless.example.com,这些配置里就不能仍以 http://IP:36070 作为主地址。
consume 目录放文件后不自动导入
如果 consume/ 是 NAS、NFS、SMB 或其他网络挂载,默认文件通知可能失效。保留轮询配置后重启:
<code class="language-env">PAPERLESS_CONSUMER_POLLING=60</code>
<code class="language-bash">docker compose --env-file docker-compose.env up -d</code>
权限问题
如果上传、消费、OCR 后写文件失败,检查 UID/GID 和目录属主:
<code class="language-bash">id -u id -g ls -la /opt/1panel/docker/compose/paperless-ngx</code>
然后调整环境变量和宿主机目录属主:
<code class="language-env">USERMAP_UID=1000 USERMAP_GID=1000</code>
<code class="language-bash">sudo chown -R 1000:1000 /opt/1panel/docker/compose/paperless-ngx/data sudo chown -R 1000:1000 /opt/1panel/docker/compose/paperless-ngx/media sudo chown -R 1000:1000 /opt/1panel/docker/compose/paperless-ngx/consume sudo chown -R 1000:1000 /opt/1panel/docker/compose/paperless-ngx/export sudo chown -R 1000:1000 /opt/1panel/docker/compose/paperless-ngx/tessdata</code>
二十、本次部署参数记录
以下只记录非敏感参数,方便以后对照:
| 项目 | 值 |
|---|---|
| 部署目录 | /opt/1panel/docker/compose/paperless-ngx |
| 访问地址 | http://YOUR_VPS_IP:36070 |
| Web 端口映射 | 36070:8000 |
| Paperless 镜像 | docker.io/paperlessngx/paperless-ngx:latest |
| PostgreSQL 镜像 | docker.io/library/postgres:16-alpine |
| Valkey 镜像 | docker.io/valkey/valkey:8-alpine |
| OCR 使用语言 | chi_sim+chi_tra+eng |
| 中文 OCR 持久化 | ./tessdata/chi_sim.traineddata、./tessdata/chi_tra.traineddata |
| 时区 | Asia/Shanghai |
| 已验证版本 | Paperless-ngx v3.0.5 |
二十一、最小检查清单
docker compose config --quiet无输出。docker ps中 3 个容器都在运行。paperless-ngx状态是 healthy。docker exec paperless-ngx tesseract --list-langs包含chi_sim、chi_tra、eng。- 浏览器打开
http://YOUR_VPS_IP:36070能进入登录页。 - 上传一份中文 PDF 或图片,OCR 后能搜索到中文内容。
- 备份任务已覆盖
media/、pgdata/、data/、docker-compose.env。
