这是「Docker 好项目」系列的第 5 期。每期挑一个真正能在自己服务器上跑起来、并且能解决具体问题的项目,给出能直接复制的配置。

你有多少次为了把一个 PDF 拆页、合并、转 Word、去个密码,把文件传到某个「免费在线工具」网站上?文件传上去那一刻,它就不在你掌控里了——内容泄露、被留存、被拿去训练模型,你都不知道。更别说那些站点动不动就限速、加水印、逼着你开会员。

Stirling-PDF 就是把这些活儿搬回自己服务器的:一个开源的 PDF 工具箱,55+ 种操作(合并、拆分、旋转、压缩、格式转换、OCR、签名、去密、红章、批注……)全在本地跑,文件不出你的机器。MIT 协议核心功能免费,单容器部署,1 核 2G 的机器就能带起来。

Stirling-PDF 效果图

它到底能干什么

先说清能力边界,避免装完发现和预期不符:

  • 格式互转:PDF ⇄ Word / Excel / PowerPoint / HTML / 图片,PDF 多页转图片、图片合成 PDF
  • 页面操作:合并、拆分、旋转、提取页面、重排、加水印、加页码、加背景、裁剪
  • 内容处理:压缩体积、OCR 识别文字(需语言包)、去密码/加密码、签名、红章、去红头、批注
  • 自动化(Pipeline):配置一条处理流水线,或监控某个文件夹,丢进去自动按规则处理,适合批量活儿
  • API:几乎每个工具都有 REST 接口,可以接到你自己的脚本或系统里
  • 多语言界面:40+ 语言,含简体中文(zh-CN)

它不做的是:它不是文档协作平台(没有多人同时编辑、评论线程那种),也不是 OCR 神器(OCR 靠 Tesseract,中文准确率够用但不是顶级),更不是「PDF 转可编辑 Word 且排版 100% 还原」的魔法——复杂排版转出来需要人工再调。它就是一把趁手的本地 PDF 瑞士军刀。

部署前准备

确认 Docker 和 Compose 插件都在:

docker --version
docker compose version

华为云这类云主机记得两件事:安全组放行后面要用的端口(反代后通常只放 80/443,8080 走内网);以及机器内存——标准镜像跑起来要吃掉 1GB 以上内存,1 核 1G 的小鸡建议直接用 latest-ultra-lite(见下文坑点)。

方式一:一行命令跑起来

先试水,只挂最核心的 /configs(设置和用户库都在这里):

docker run -d --name stirling-pdf --restart=unless-stopped \
  -p 8080:8080 \
  -v stirling-configs:/configs \
  stirlingtools/stirling-pdf:2.14.3

镜像名用 stirlingtools/stirling-pdf(Docker Hub 官方组织仓库)。老的 frooodle/s-pdf 已重定向到它,别再用了。tag 固定 2.14.3——Stirling-PDF 的 CI 只发布完整版本号 tag 和 latest 系列,没有 :2 这种主版本 tag,所以不要图省事写 :2(拉不到),也绝对别写 :latest(滚动标签,哪天大版本升级悄悄把你的环境变了)。

方式二:docker-compose(推荐)

正式用一定写成文件。新建目录并进入:

mkdir -p /opt/stirling-pdf && cd /opt/stirling-pdf

新建 docker-compose.yml:

services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:2.14.3
    container_name: stirling-pdf
    restart: unless-stopped
    # 只监听本机回环,8080 不暴露公网,前面用反代挡 HTTPS
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - ./data/configs:/configs        # 设置 + 用户数据库,唯一必须备份的
      - ./data/tessdata:/usr/share/tessdata  # OCR 语言包
      - ./data/logs:/logs
      - ./data/pipeline:/pipeline       # 自动化流水线配置
    environment:
      - TZ=Asia/Shanghai
      - SECURITY_ENABLELOGIN=true       # v2 默认就是开,显式写出来防以后改默认行为
      - SECURITY_INITIALLOGIN_USERNAME=admin   # 首次启动建的管理员账号
      - SECURITY_INITIALLOGIN_PASSWORD=换一个强密码
      - DISABLE_ADDITIONAL_FEATURES=false      # 保留登录等附加功能(标准镜像本来就有)
      - SYSTEM_DEFAULTLOCALE=zh-CN      # 界面默认简体中文
      - SYSTEM_MAXFILESIZE=200          # 单文件上限 MB
      - SYSTEM_FRONTENDURL=https://pdf.你的域名   # 反代后必填,否则登录跳转会带错 host
      - SYSTEM_CORSALLOWEDORIGINS=https://pdf.你的域名
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

启动:

docker compose up -d
docker compose logs -f stirling-pdf

看到日志里端口起来、healthcheck 变 healthy 就说明 OK 了。

几个配置项为什么要这么写

这一段重点,照抄容易、抄错也容易:

配置 说明
image: ...:2.14.3 固定到发版版本。CI 只推完整版本号(如 2.14.3)和 latest,没有 :2/2.14 这种短 tag,latest 是滚动标签,升级会静默跨版本
127.0.0.1:8080:8080 只绑本机。Docker 端口映射走 DNAT,优先级高于 ufw/iptables,直接写 8080:8080 等于把面板裸奔到公网
./data/configs:/configs 设置、登录用户、数据库全在这,这是唯一必须备份的目录;只挂它也能跑,其余卷是锦上添花
SECURITY_ENABLELOGIN=true v2 默认登录就是开的,初始账号 admin / stirling 且首次登录强制改密。显式写出来,避免哪天你换了镜像忘了这茬
SECURITY_INITIALLOGIN_* 用环境变量在首次启动时把管理员账号设成你自己的,省得用默认 admin/stirling 留后门
SYSTEM_DEFAULTLOCALE=zh-CN 不设这个,界面默认英文,你每次都得手动切语言
SYSTEM_FRONTENDURL + CORSALLOWEDORIGINS 反代后最容易漏的两项。不填,登录后会跳到 http://localhost:8080 或报 CORS 错误,页面打不开
healthcheck 让 Docker 自己判断容器是否真健康,配 Watchtower 自动更新时更稳

在 1Panel 里怎么搞

如果你用 1Panel,有两种走法:

  1. 容器 → 编排 → 创建编排,把上面的 docker-compose.yml 整段贴进去,填个名称(如 stirling-pdf)直接启动,端口和存储卷一次配好
  2. 容器 → 创建容器,按上面的参数逐项填:镜像 stirlingtools/stirling-pdf:2.14.3、端口映射 127.0.0.1:8080:8080、挂载 /configs 等卷、环境变量照填

装完去 防火墙 / 安全组 确认只放行了 80/443(反代用),8080 不对外。HTTPS 和域名在「网站 → 反向代理」里做(见下节)。

1Panel 应用商店目前没有内置 Stirling-PDF 官方应用,所以用编排最稳,参数完全自己掌控。

首次访问:先改管理员密码

浏览器打开 http://服务器IP:8080(或你配的域名)。v2 默认开启登录,第一屏是登录页:

  • 用户名:admin
  • 密码:stirling

首次登录会被强制要求改密码——这步别跳过,默认密码等于把后台门虚掩着。前面用 SECURITY_INITIALLOGIN_* 设了自定义账号的话,就用那个登。

Stirling-PDF 工作台

进主页后左边是 55+ 个工具分类,挑一个试就行。中文界面在右上角头像 → Settings → General → Language 里也能随时切。

最小可用配置

如果你只是自己偶尔用、不需要账号体系,可以关掉登录、少挂几个卷,最小这样:

services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:2.14.3
    container_name: stirling-pdf
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - ./data/configs:/configs
    environment:
      - TZ=Asia/Shanghai
      - SECURITY_ENABLELOGIN=false     # 关掉登录,谁都能用(仅限内网/反代带认证的场景)
      - SYSTEM_DEFAULTLOCALE=zh-CN

关登录会同时关掉「附加功能」(API 高级能力、签名校验等)。SECURITY_ENABLELOGIN=false 时要把 DISABLE_ADDITIONAL_FEATURES=false 也加上,功能才全。个人内网用无所谓;一旦走公网,务必保留登录。

自动化与 Pipeline(让处理不用人盯着)

Stirling-PDF 不是监控工具,没有「挂了推报警」那套(那是 Uptime Kuma 的活)。但它有一类很实用的「设完就忘」能力——Pipeline 自动化:

  • 在 Settings → Automation 里建一条流水线,比如「收到 PDF → 压缩到 70% → 加页码水印 → 导出到某目录」
  • 配合 /pipeline 卷,流水线配置会持久化
  • 还能监控一个文件夹:文件丢进去按规则自动处理完,适合批量合同/报表归档

这部分替代了「告警/通知」的位置——它的价值是减少人工重复操作,而不是通知你出事。需要真出事报警,请回头看第 1 期的 Uptime Kuma。

套上域名和 HTTPS

用 1Panel 最省事:网站 → 反向代理 → 新建,代理地址填 http://127.0.0.1:8080,域名填 pdf.你的域名,然后一键申请 Let's Encrypt 证书开 HTTPS。

单独用 Nginx 的话,配置如下(注意 WebSocket 升级头和那两个 env 要对应):

server {
    listen 80;
    server_name pdf.example.com;
    # 先让证书申请通过,后再补 443
    location /.well-known/acme-challenge/ { root /var/www/certbot; }
    location / { return 301 https://$host$request_uri; }
}

server {
    listen 443 ssl;
    server_name pdf.example.com;

    ssl_certificate     /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    client_max_body_size 200M;   # 得和 SYSTEM_MAXFILESIZE 对上,否则大文件被 Nginx 拦

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;

        # Stirling-PDF 有实时类功能,升级头加上更稳,不加可能某些交互卡住
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

配完别忘了把 compose 里的 SYSTEM_FRONTENDURL 和 SYSTEM_CORSALLOWEDORIGINS 改成你的 https://pdf.你的域名,然后 docker compose up -d 重启生效。

踩坑清单

  • 默认 admin / stirling 必须改密码。这是头号风险,装完第一件事就是登进去改
  • 反代后页面打不开 / 登录循环:九成是漏了 SYSTEM_FRONTENDURL 或 CORSALLOWEDORIGINS,补上重启
  • OCR 中文识别不了:标准镜像只带英文语言包。去 Settings → OCR 下载 chi_sim(简体中文),或把语言包放进 /usr/share/tessdata 卷;没挂这个卷则每次重启得重下
  • 小内存机器起不来 / 频繁 OOM:标准镜像吃 1GB+ 内存,1 核 1G 的云主机换 stirlingtools/stirling-pdf:2.14.3-ultra-lite(体积最小、关掉部分高级功能),或干脆 latest-ultra-lite
  • 想批量处理别手点:用 Pipeline + 文件夹监控,比一个个拖进去点按钮快得多
  • 升级前先备份 ./data/configs:跨大版本配置结构可能变,回不去

备份

就一句话——定期打包 ./data/configs:

cd /opt/stirling-pdf
tar czf stirling-backup-$(date +%F).tar.gz data/configs/

配合 crontab 或 1Panel 计划任务每周跑一次,丢到对象存储。用户账号、设置、Pipeline 全在这一份里。

小结

Stirling-PDF 属于「早该装」的那种工具:以后任何 PDF 操作都在自己机器上 10 秒搞定,不用再纠结文件传没传给别人。

适合:经常处理 PDF、在意文件隐私、想摆脱在线工具限速水印的个人或团队。
不适合:需要顶级 OCR 准确率(上专业 OCR 引擎)、需要多人实时协作编辑、或期待「复杂排版 PDF 完美转 Word」的场景——那是另一类商业产品的活。

下期继续聊另一个 Docker 项目。


项目地址:https://github.com/Stirling-Tools/Stirling-PDF
官方文档:https://docs.stirlingpdf.com
当前版本:v2.14.3(2026-08-06 发布)