Paperless-ngx 部署实战:安装脚本、Docker Compose、Bare Metal 与迁移指南
本文基于 Paperless-ngx 仓库中的 部署文档 展开,系统讲解四条安装路径——交互式安装脚本、Docker Compose 手工部署、裸机(Bare Metal)部署,以及从 Paperless-ng / Paperless / LinuxServer.io 镜像的迁移方法。读完本文,你可以完成 Paperless-ngx 的完整落地:从选择安装方式、配置数据库与消费目录,到配置 systemd 服务、调优低功耗设备参数,并掌握迁移旧实例的操作细节。
一、选择安装路径
Paperless-ngx 提供了四种部署方式,官方文档给出了明确的选择建议:
| 路径 | 适用场景 | 工作量 |
|---|---|---|
| 交互式安装脚本 | 首次部署最快的引导式配置(多数用户推荐) | 低 |
| Docker Compose 模板 | 需要手工控制 compose 文件与各项设置 | 中 |
| 裸机安装 | 高级部署、打包发布、贴近开发的工作流 | 高 |
| 社区托管服务商 | 社区维护的托管方案,需自行确认细节 | 不定 |
官方结论是:对大多数用户,Docker 是最佳选择——部署更快、维护更容易,且内置了合理的默认值;裸机路线控制力更强,但需要手动安装并运维全部组件,通常更适合高级用户与贡献者。
一个安全提醒:superuser 账号拥有对全部对象和文档的完全访问权,建议为日常使用单独创建普通用户账号,或在部署完成后把 superuser "降级"为普通用户(参见 使用文档中的 superuser 章节)。
二、交互式安装脚本:一条命令完成 Docker Compose 部署
Paperless-ngx 仓库根目录提供了 install-paperless-ngx.sh 脚本,它会自动完成:生成配置文件、拉取镜像、启动容器、创建 superuser 账号。
前置条件
- 已安装 Docker 与 Docker Compose(参考 Docker 官方安装文档);
- macOS 用户需要支持以
sed运行的 GNU sed(含gsed能力)以及wget。
运行脚本
bash -c "$(curl --location --silent --show-error https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/install-paperless-ngx.sh)"
如果对直接从互联网向 shell 管道执行命令感到不安,可以先在仓库中查看 install-paperless-ngx.sh 的完整内容再执行。
脚本内部到底做了什么(源码视角)
从 install-paperless-ngx.sh 的源码看,这个脚本并非黑盒,它的执行流程可以完整还原:
-
前置检查(第 44–72 行):拒绝以 root 运行;依次检查
wget、docker、docker compose插件是否存在,并通过docker stats --no-stream探测当前用户是否有 Docker 权限,若无则提示用sudo usermod -aG docker $USER授权。 -
时区探测(第 76–84 行):优先用
timedatectl show -p Timezone --value;针对 QNAP 等基于 busybox 的系统回退到读取/etc/TZ与/etc/tzlist;都失败则默认Etc/UTC。 -
交互式问答:依次询问 Web URL(反代场景必填)、端口(默认 8000)、时区、数据库后端(
postgres/sqlite/mariadb,不确定时选 PostgreSQL,低配设备如树莓派建议 SQLite)、是否启用 Apache Tika(用于解析 Office 文档)、OCR 语言(ISO 639-2 T 变体,如eng、deu+eng)、USERMAP_UID/GID(默认取当前用户的id -u/id -g)、目标文件夹、consume 文件夹(必须是/或./开头)、media / data / 数据库文件夹(留空则由 Docker 卷管理),以及初始用户名、密码、邮箱(邮箱不被实际使用,填占位值即可)。 -
生成三个文件:根据选择的数据库与 Tika 开关,从仓库下载对应的
docker-compose.<backend>[-tika].yml另存为docker-compose.yml,再下载.env;随后生成docker-compose.env,其中包含PAPERLESS_URL(如填写)、非 1000 的USERMAP_UID/USERMAP_GID、PAPERLESS_TIME_ZONE、PAPERLESS_OCR_LANGUAGE,以及一个从/dev/urandom生成的 64 字符PAPERLESS_SECRET_KEY。若 OCR 语言不在容器默认预装的五种语言(deu eng fra ita spa)之列,还会追加PAPERLESS_OCR_LANGUAGES让容器额外安装语言包。 -
改写 compose 文件:用
sed将8000:8000端口映射改为实际端口,把./consume换成用户指定的消费目录;若指定了 media / data / 数据库目录,则把对应的命名卷替换为 bind mount 并删除声明。 -
初始化并启动:执行
docker compose pull;若使用 PostgreSQL 或 MariaDB,会先单独up数据库容器并等待 15 秒完成初始化;然后运行docker compose run --rm -e DJANGO_SUPERUSER_PASSWORD="$PASSWORD" webserver createsuperuser --noinput --username "$USERNAME" --email "$EMAIL"创建超级用户,最后
docker compose up --detach完成部署。
安装完成后
实例默认在 http://127.0.0.1:8000(随配置而定)可访问,使用安装时提供的凭据登录。
三、Docker Compose 手工安装
适合需要逐项确认与调整每个配置的用户。
前置条件
已安装 Docker 与 Docker Compose。
安装步骤
1. 下载 compose 文件。 从仓库的 docker/compose 目录 下载与目标数据库匹配的模板,保存为 docker-compose.yml,同时把 docker-compose.env 和 .env 放入同一目录。可选模板:
- docker-compose.sqlite.yml —— SQLite(默认、最轻量)
- docker-compose.postgres.yml —— PostgreSQL(新装推荐)
- docker-compose.mariadb.yml —— MariaDB
- 带
-tika后缀的文件(如 docker-compose.postgres-tika.yml)——额外启用 Apache Tika 支持 Office 等文档格式 - docker-compose.portainer.yml 用于 Portainer 环境
以 PostgreSQL 模板 docker/compose/docker-compose.postgres.yml 为例,它由三个服务组成:
broker:valkey/valkey:9-alpine,作为任务队列的消息代理(Valkey 是 Redis 兼容的分支);db:postgres:18,初始化POSTGRES_DB/USER/PASSWORD均为paperless;webserver:ghcr.io/paperless-ngx/paperless-ngx:latest,depends_on数据库与 broker,映射端口8000:8000,挂载data、media两个命名卷以及./export、./consume两个 bind mount,并通过env_file: docker-compose.env注入配置。
.env 中仅有一行 COMPOSE_PROJECT_NAME=paperless,它决定了 compose 项目名以及由此派生的卷名前缀。
2. 修改 docker-compose.yml。 典型改动是把容器内目录绑定到宿主机路径,例如把
- ./consume:/usr/src/paperless/consume
改为
- /home/jonaswinkler/paperless-inbox:/usr/src/paperless/consume
冒号前是宿主机目录,冒号后保持不变。还可以修改 Web 端口,例如使用 8010:
ports:
- 8010:8000
3. 修改 docker-compose.env。 所有配置项参见 配置文档。其中两点特别注意:
- 把
USERMAP_UID/USERMAP_GID设为宿主机用户的 UID/GID(用id -u和id -g查询),保证容器与宿主机用户都能写消费目录;如果你的 UID/GID 恰是 1000(很多系统第一个普通用户的默认值),通常无需改动。仓库中的 docker-compose.env 给出了完整注释,包括必填的PAPERLESS_SECRET_KEY(可用python3 -c "import secrets; print(secrets.token_urlsafe(64))"生成)、PAPERLESS_URL、PAPERLESS_TIME_ZONE、PAPERLESS_OCR_LANGUAGE,以及PAPERLESS_OCR_LANGUAGES(容器默认预装英、德、意、西、法五种语言包)。 - 支持 Docker secrets:给任意配置项追加
_FILE后缀即可从文件读取,例如用PAPERLESS_DBUSER_FILE=/var/run/secrets/password.txt代替明文PAPERLESS_DBUSER。
4. 拉取镜像。 运行 docker compose pull。默认从 GitHub 容器注册表拉取;如需改用 Docker Hub,把 image 行改为 paperlessngx/paperless-ngx:latest。
5. 启动。 运行 docker compose up -d 创建并启动容器。
安装完成后
访问 http://127.0.0.1:8000(或你配置的地址/端口),首次进入 Web 界面会提示创建 superuser 账号。
进阶 Compose 配置
Rootless 容器。 注意:如果通过 PAPERLESS_OCR_LANGUAGES 指定了额外语言包,无法以 rootless 方式运行容器。想要 rootless 运行时,在 docker-compose.yml 中把 user: 设为宿主机用户的 UID/GID(id -u、id -g 查询),容器进程直接以该用户启动、无内部权限重映射:
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
user: '1000:1000'
此方式不要与 USERMAP_UID/USERMAP_GID 混用——那两个变量是为非 rootless 场景设计的。
不支持 inotify 的文件系统(如 NFS)。 NFS 网络共享等文件系统不支持 inotify 文件通知。当消费目录位于这类文件系统上时,默认配置下 Paperless-ngx 无法发现新文件。把 PAPERLESS_CONSUMER_POLLING_INTERVAL 设为正数以启用轮询、关闭原生文件系统通知即可。
四、裸机(Bare Metal)安装
前置条件
- 仅支持 Linux,不支持 Windows;
- 需要 Python 3.11、3.12、3.13 或 3.14。项目策略是至少支持最近三个 Python 版本并随 EOL 移除旧版本;仓库 pyproject.toml 中声明
requires-python = ">=3.11",与之一致。更高版本可能可用,但部分依赖未必完全兼容。
安装步骤
1. 安装系统依赖。 Paperless 要求的包(Debian 风格命名,请按发行版转换):
python3 python3-pip python3-dev imagemagick fonts-liberation gnupg libpq-dev default-libmysqlclient-dev pkg-config libmagic-dev poppler-utils
各包用途:default-libmysqlclient-dev + pkg-config 供 MariaDB 与 mysqlclient 使用;fonts-liberation 用于纯文本文件缩略图;imagemagick(>= 6)用于 PDF 转换;gnupg 用于解密 GPG 加密邮件;libpq-dev 用于 PostgreSQL;libmagic-dev 用于 MIME 类型检测;mariadb-client 供 MariaDB 编译期;poppler-utils 用于条形码检测。
OCRmyPDF(文本识别引擎)还依赖:
unpaper ghostscript icc-profiles-free qpdf liblept5 libxml2 pngquant zlib1g tesseract-ocr
其中 tesseract-ocr 需 >= 4.0.0,并安装所需语言包(tesseract-ocr-eng、tesseract-ocr-deu 等);pngquant 建议安装,用于部分 PDF 图像优化。
树莓派额外需要:libatlas-base-dev、libxslt1-dev、mime-support。
安装部分 Python 依赖还需要:
build-essential python3-setuptools python3-wheel
2. 安装 Redis 兼容的消息代理(Valkey 或 Redis 的当前版本),并配置为开机自启。
3. (可选)安装 PostgreSQL 并配置数据库、用户与密码。若不用 PostgreSQL,MariaDB 和 SQLite 均可用。使用 SQLite 时需确认 JSON1 扩展已启用(大多数发行版默认开启,但不保证)。
4. 创建系统用户:
adduser paperless --system --home /opt/paperless --group
5. 下载发布包。 从项目 Releases 页下载对应版本,例如:
curl -O -L https://github.com/paperless-ngx/paperless-ngx/releases/download/vX.Y.Z/paperless-ngx-vX.Y.Z.tar.xz
解压并复制到用户主目录:
tar -xf paperless-ngx-vX.Y.Z.tar.xz
注意:如果是升级已有裸机安装,应查阅 administration 文档中的裸机升级章节,在旧版本上直接覆盖解压会残留旧版本文件。若你克隆了 Git 仓库开发,则需自行编译前端(参见 development 文档的前端章节,使用 build 而非 serve 步骤)。
6. 配置 Paperless-ngx。 编辑包内自带的 paperless.conf,最小可运行配置为:
PAPERLESS_REDIS:指向消息代理,如redis://localhost:6379;PAPERLESS_DBENGINE:postgresql、mariadb或sqlite之一;PostgreSQL 与 MariaDB 用户必须显式设置;PAPERLESS_DBHOST:PostgreSQL 服务器主机名(注意:不要借此改用 SQLite),按需配置端口、库名、用户、密码;PAPERLESS_CONSUMPTION_DIR:监听的收件目录;PAPERLESS_DATA_DIR与PAPERLESS_MEDIA_ROOT定义数据与媒体存储位置,必要时可以指向同一目录;PAPERLESS_SECRET_KEY:一段随机字符,用于认证签名;不设置将允许第三方伪造认证凭据;PAPERLESS_URL:位于反向代理后时必须设置,指向你的域名。
建议为大多数用户设置的 OCR 相关项:
PAPERLESS_OCR_LANGUAGE:文档的主要语言;PAPERLESS_TIME_ZONE:本地时区。
警告:务必保障消息代理实例本身的安全性(如密码与网络隔离)。
7. 创建目录并校验权限。 默认创建:
/opt/paperless/media/opt/paperless/data/opt/paperless/consume
(若配置了不同路径则相应调整)用 ls -l -d /opt/paperless/media 等确认 paperless 用户可写,必要时:
sudo chown paperless:paperless /opt/paperless/media
sudo chown paperless:paperless /opt/paperless/data
sudo chown paperless:paperless /opt/paperless/consume
8. 安装 Python 依赖:
sudo -Hu paperless pip3 install -r requirements.txt
依赖会装到 paperless 用户主目录。也可以改用虚拟环境(注意相应调整示例脚本中的路径)。如果使用 uv 等现代工具,默认安装不含 PostgreSQL / MariaDB 驱动,可用 --extra <EXTRA> 选择,或 --all-extras 全部安装。
9. 初始化数据库结构:
# 在 /opt/paperless/src 下执行,创建数据库 schema
sudo -Hu paperless python3 manage.py migrate
10. (可选)冒烟测试:
# 手动启动 Web 服务器(开发服务器,勿用于生产)
sudo -Hu paperless python3 manage.py runserver
然后访问 http://localhost:8000。跨机器访问时需要配置 systemd 服务,且可能需要 PAPERLESS_DEBUG=true 才能让开发服务器正常工作。注意该命令不会启动 consumer——文档消费是独立进程。
11. 配置 systemd 服务。 仓库 scripts 目录提供了服务定义文件作为起点:
| 服务文件 | 职责 |
|---|---|
| paperless-webserver.service | 运行 Web 服务器 |
| paperless-consumer.service | 监控输入文件夹 |
| paperless-task-queue.service | 后台 worker(文档消费等) |
| paperless-scheduler.service | 周期性任务(如邮件检查) |
从源码看,paperless-webserver.service 通过 granian --interface asginl --ws --loop uvloop "paperless.asgi:application" 启动,默认 GRANIAN_PORT=8000,且 Requires=redis.service;paperless-task-queue.service 与 paperless-scheduler.service 分别执行 celery --app paperless worker 和 celery --app paperless beat;paperless-consumer.service 执行 python3 manage.py document_consumer。四个服务都依赖 broker(示例文件 Requires=redis.service),彼此之间无强制启动顺序;若使用外部数据库,还应补充相应依赖。
两点补充:
paperless-webserver.socket可让 granian 免 root 监听 80 端口:需要取消webserver单元中Require=paperless-webserver.socket的注释,并设置GRANIAN_PORT=80。- 如果 Celery 起不来,检查
sudo systemctl status paperless-task-queue.service与paperless-scheduler.service,可能需修改 ExecStart 中的路径,例如ExecStart=/opt/paperless/.local/bin/celery --app paperless worker --loglevel INFO。
12. 配置 ImageMagick policy。 多数发行版默认禁用 ImageMagick 的 PDF 处理(PDF 可能携带恶意代码),不禁用则 Paperless-ngx 会在缩略图生成等步骤回退到 Ghostscript。配置当前生效的 policy 文件(常见于 /etc/ImageMagick-6/policy.xml 或 /etc/ImageMagick-7/policy.xml),参考仓库中的 paperless-policy.xml——它放开 PDF 读写的同时设置了资源上限(memory 256MiB、map 512MiB、area 128MB、disk 1GiB 等)并禁用不需要的 coder,建议连同这些限制一并采纳。
可选项:
- 编译安装 jbig2enc 编码器,可减小生成的 PDF 体积(该软件专利约 2017 年后到期,多数发行版无二进制包,通常需自行编译);
- 若使用 NLTK 机器学习处理(见
PAPERLESS_ENABLE_NLTK),下载 Snowball Stemmer、Stopwords、Punkt tokenizer 数据到/usr/share/nltk_data。
安装完成后
实例在 http://localhost:8000(或随配置)可访问,首次访问提示创建 superuser 账号。
五、自行构建 Docker 镜像
自行构建镜像主要用于开发场景,但生产环境如需定制镜像也可用。具体步骤参见 development 文档中的镜像构建章节。
六、迁移到 Paperless-ngx
从 Paperless-ng 迁移
Paperless-ngx 是 Paperless-ng 的 drop-in 替代,使用 Docker 时升级几乎零成本(但重大变更前仍建议完整备份)。只需把 docker-compose.yml 中
image: jonaswinkler/paperless-ng:latest
改为
image: ghcr.io/paperless-ngx/paperless-ngx:latest
然后 docker compose up -d 拉取新镜像并重建容器即可。裸机用户则把 Git remote 指向 Paperless-ngx 仓库并拉取最新代码。
从 Paperless(原版)迁移
Paperless-ngx 内核仍是 Paperless,完全兼容,但底层有变化。要点:
- 阅读 changelog,注意破坏性变更;
- 决定留在 SQLite 还是迁移到 PostgreSQL,两者都可用;已有数据库服务器的不妨一并使用;
- 周期任务(邮件检查、维护等)需要 Redis 兼容的消息代理实例(Valkey/Redis),Docker Compose 路线已内置;
- 文档与数据的目录布局保持不变,旧 Docker 卷可直接挂给 paperless-ngx。
操作步骤:
-
停止旧实例:
cd /path/to/current/paperless docker compose down -
创建备份——既防迁移出错,也保留回滚到 Paperless 的可能。
-
获取 Paperless-ngx:使用仓库中的 Compose 文件或克隆仓库自建镜像;可以替换现有 paperless 目录,也可以放在新位置。 注意:Paperless-ngx 的
.env会把 Compose 项目名设为paperless,卷名随之确定。如果发现新实例没找到旧卷,用docker volume ls | grep _data查看实际卷名,并调整
.env中项目名,使其与卷名中_data前缀部分一致。 -
下载
docker-compose.sqlite.yml作为docker-compose.yml;若要换 PostgreSQL,先完成 SQLite 数据迁移后再切换。 -
按上文 Docker 章节调整
docker-compose.yml与docker-compose.env。 -
按 administration 文档的升级流程 执行更新。
-
用一次性操作重建搜索索引:
docker compose run --rm webserver document_index reindex该命令会迁移数据库并创建索引,之后 Paperless-ngx 自动维护。
-
启动:
docker compose up -d -
旧 Paperless 可能在浏览器里留下了指向
admin/的永久重定向,会挡住新界面——清除浏览器缓存即可。 -
(可选)按上述方案把数据迁移到 PostgreSQL。
从 LinuxServer.io 镜像迁移
同样先备份。假设原实例用 Docker Compose 运行(可平移到 docker 命令):
- 停止并移除 Paperless 容器;若使用外部数据库容器,一并停止。
- 更新 broker 配置:已有
REDIS_URL的改名为PAPERLESS_REDIS;否则参照仓库 compose 示例 新增 broker 服务,再把PAPERLESS_REDIS指向它。 - 用户映射:
PUID改USERMAP_UID,PGID改USERMAP_GID。 - 路径映射:
PAPERLESS_DATA_DIR设为/config,PAPERLESS_MEDIA_ROOT设为/data/media。 - 时区:
PAPERLESS_TIME_ZONE设为原TZ的值。 - 把
image:指向ghcr.io/paperless-ngx/paperless-ngx:latest(或指定版本)。 - 照常
docker compose启动。
七、低功耗设备(树莓派)调优
Paperless 可以运行在树莓派上,部分任务在低性能硬件上较慢,文档建议的组合拳是:
- 使用 SQLite 节省资源;若遇到 SQLite 锁问题,参见 troubleshooting 文档;
- 不用文件系统消费目录的,设
PAPERLESS_CONSUMER_DISABLE为true彻底禁用; PAPERLESS_OCR_PAGES设为 1,只 OCR 首页——多数情况下首页信息足以定位文档;PAPERLESS_TASK_WORKERS与PAPERLESS_THREADS_PER_WORKER默认吃满所有核心(4 核树莓派即 2 workers × 2 threads),消费期间可能导致响应迟钝,可降为 2 workers × 1 thread;PAPERLESS_OCR_MODE保持默认auto,尽量在扫描器端预 OCR;PAPERLESS_ARCHIVE_FILE_GENERATION设为never跳过归档文件生成,省磁盘,代价是没有浏览器内 PDF/A 预览;- 在设备上做 OCR 时可设
PAPERLESS_OCR_CLEAN=none,更快更省内存,识别质量略降; - Docker 部署可设
PAPERLESS_WEBSERVER_WORKERS为 1 省内存; - 设
PAPERLESS_ENABLE_NLTK为 false,关闭更耗资源的语言处理。
另外,自动匹配算法 的训练更新耗时较长,但更新机制会先检查数据是否有变化再动真格;若 CPU 时间过长,可在管理界面把调度改为每日一次,或手动把下次运行时间改到当前立即触发——实际匹配阶段很快,树莓派也毫无压力。
八、更多注意事项
- 反向代理:nginx 等反向代理配置以项目 Wiki 中社区维护的文档为准,重点是把
PAPERLESS_URL指向你的域名; - 安全加固:Fail2ban 等安全工具与 Paperless-ngx 的结合同样参见项目 Wiki 的社区文档;
- 升级提醒:从 Paperless-ngx v2 升级到 v3 有独立的破坏性变更与必做步骤,升级前务必先阅读 v3 迁移指南。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00