Stirling-PDF 深度導讀
把一支 GitHub 上 79K stars 的開源專案,從定位到資安一次講完。 適合:想為團隊 / 客戶導入 self-hosted PDF 處理平台的工程師、IT 與資安人員。
1. 專案定位
Stirling-PDF 在 PDF 工具光譜上的座標:
| 構面 | Stirling-PDF | Adobe Acrobat | pdftk / qpdf | pdf.js / PSPDFKit |
|---|---|---|---|---|
| 部署 | self-hosted(Docker / Desktop / K8s) | 桌面 + 雲(Adobe 控制) | CLI only | SDK / SaaS |
| 介面 | 瀏覽器 UI + Desktop + REST API + Pipeline | 桌面 GUI | 無 | SDK / library |
| 工具數 | 50+(合併 / 拆分 / OCR / 簽署 / redact / 轉檔) | 100+ | ~10 | 視 SDK |
| 隱私 | 完全本地(檔案不出機器) | 雲傳輸 | 本地 | 視部署 |
| 授權 | open-core(免費核心 + 付費 Enterprise) | 商用 | 開源 | 商用 |
| 語系 | 40+ 語系 | 主流幾種 | N/A | N/A |
| 適用場景 | 內部 PDF 平台 / API 整合 / 法務 / 醫療 | 個人 / SMB | 開發者腳本 | App 內 PDF |
一句話:當你需要一個「能放進公司 DMZ、不會把客戶 PDF 送到 Adobe 雲、又有 Acrobat 級工具數量」的 PDF 平台時,Stirling-PDF 是現階段最成熟的開源選項。
2. 安裝指南
2.1 最快路徑:Docker 一行(5 分鐘)
1docker run -p 8080:8080 docker.stirlingpdf.com/stirlingtools/stirling-pdf
開瀏覽器到 http://localhost:8080 即可使用。
2.2 三種 image 變體
| Tag | 大小 | 含 LibreOffice / OCR | 適用 |
|---|---|---|---|
:latest | ~1.5 GB | ✅ | 一般推薦 |
:latest-ultra-lite | ~400 MB | ❌ | 純 PDF 操作、資源受限 |
:latest-fat | ~3 GB | ✅ + 預載字型 / lib | 冷啟動敏感、企業 |
2.3 docker-compose(建議:unified-both + 持久化 volume)
1services:
2 stirling-pdf:
3 image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
4 container_name: stirling-pdf
5 ports:
6 - "8080:8080"
7 volumes:
8 - ./stirling-data/configs:/configs
9 - ./stirling-data/logs:/logs
10 - ./stirling-data/tessdata:/usr/share/tessdata
11 - ./stirling-data/pipeline:/pipeline
12 environment:
13 LANGS: en_GB,zh_TW
14 SECURITY_ENABLELOGIN: "true"
15 SECURITY_JWT_PERSISTENCE: "true"
16 SECURITY_JWT_ENABLEKEYROTATION: "true"
17 SYSTEM_MAXFILESIZE: "100"
18 deploy:
19 resources:
20 limits:
21 cpus: "1.0"
22 memory: 2048M
23 restart: unless-stopped
啟動:docker compose up -d
2.4 Desktop client(Tauri)
從 Releases 下載對應平台:
.dmg(macOS,v2.10.1 起為 unified installer).exe(Windows).AppImage/.rpm/.deb(Linux,v2.10.0 起新增)
桌面版內嵌 JRE + backend,雙擊即用、不需 Docker。
2.5 開發環境(Task + Gradle)
1# 一次安裝所有開發依賴
2task install
3
4# 啟動本地開發
5task dev
6
7# 跑測試套件
8task test
詳細見 DeveloperGuide.md。
3. 核心架構解析
Stirling-PDF 是典型的「前後端分離 + 外部 binary 編排」架構:
flowchart TD
User[使用者瀏覽器 / Desktop / curl]
Frontend[Frontend SPA
React + Svelte + Tauri
frontend/editor]
API[Spring Boot REST API
app/core ~50 controllers]
PDFBox[Apache PDFBox
核心 PDF 解析]
Engine[Python engine
engine/ 輔助處理]
LibreOffice[LibreOffice
Office → PDF]
Tesseract[Tesseract OCR
掃描檔文字識別]
QPDF[qpdf / unoserver
底層操作]
User --> Frontend
User --> API
Frontend --> API
API --> PDFBox
API --> Engine
API --> LibreOffice
API --> Tesseract
API --> QPDF
關鍵設計:
多模組 Gradle 專案(
settings.gradle):app/common— 共用 model / utilityapp/core— 50+ controller + service(自由 open-source 核心)app/proprietary— 付費功能(SSO、audit、enterprise)app/saas— SaaS 模式(Supabase 整合)engine/— Python 輔助 engine(與 Java backend 透過 subprocess / HTTP 互通)
Controller 群組(
app/core/src/main/java/.../controller/api/):- 基本操作:
MergeController/SplitPDFController/RotationController/CropController/RearrangePagesPDFController/ScalePagesController - 進階:
EditTableOfContentsController/EditTextController/BookletImpositionController/PdfOverlayController/PosterPdfController - 子資料夾:
converters//filters//form//security//misc//pipeline/
- 基本操作:
外部 binary probe(
ExternalAppDepConfig):用ProcessBuilder+ timeout 在啟動時探測 LibreOffice / unoserver / qpdf 等是否可用,可用就啟用對應 controller,不可用就 disable,這是「同一 image 支援 ultra-lite / standard / fat」的核心機制。資料持久化:
- 預設用 H2 嵌入式 DB(檔案存
/configs/stirling-pdf-DB-*.mv.db) - 可切換成 PostgreSQL(見
DATABASE.md與官方 External Database 文件) - ⚠️ H2 不支援多容器共用(已知問題 #6395),如需橫向擴展,請改用 PostgreSQL
- 預設用 H2 嵌入式 DB(檔案存
安裝流程圖
flowchart LR
A[選擇部署模式] --> B{需求}
B -->|快速試用| C[docker run
單行命令]
B -->|生產內部用| D[docker-compose
+ volume 持久化]
B -->|個人桌面| E[下載 Tauri
installer]
B -->|企業| F[K8s + PostgreSQL
+ SSO]
C --> G[localhost:8080]
D --> G
E --> H[本機 file://]
F --> I[內部域名]
4. Docker compose 與部署選項
docker/compose/ 提供 6 種範本,依用途選擇:
| 檔案 | 用途 |
|---|---|
docker-compose.yml | 最簡單(demo 站使用) |
docker-compose.fat.yml | fat image,預載字型 |
docker-compose.ultra-lite.yml | 最小化(不含 LibreOffice / OCR) |
docker-compose-unified-both.yml | 推薦:單容器同時跑 backend + frontend |
docker-compose-unified-backend.yml | 只跑 backend(適合 API-only 整合) |
docker-compose-unified-frontend.yml | 只跑 frontend(接外部 backend) |
docker/embedded/compose/ 另有 6 個更貼近真實場景的範本:
docker-compose-latest-security.yml— 啟用登入 / 權限docker-compose-latest-fat-security.yml— fat + 登入docker-compose-latest-security-remote-uno.yml— 把 unoserver 拆到獨立容器docker-compose-latest-fat-endpoints-disabled.yml— 部分 endpoint 停用(縮小攻擊面)
重要環境變數:
| 變數 | 預設 | 說明 |
|---|---|---|
SECURITY_ENABLELOGIN | false | 啟用登入(生產環境必開) |
SYSTEM_DEFAULTLOCALE | en-US | 預設語系 |
SYSTEM_MAXFILESIZE | 100 | 上傳 PDF 上限(MB) |
LANGS | 全部 | 啟用的語系(如 en_GB,zh_TW) |
SECURITY_JWT_PERSISTENCE | false | JWT key 持久化(多 instance 必開) |
DISABLE_ADDITIONAL_FEATURES | true | 關閉付費功能 |
METRICS_ENABLED | false | 暴露 Prometheus metrics |
REST API:/api/v1/...(健康檢查 /api/v1/info/status 應回 UP)
5. 應用場景
場景 A:法務 / 合約團隊內部 PDF 平台
- 痛點:合約不能丟到 SmallPDF / iLovePDF
- 解法:內部 server 跑 Stirling-PDF + SSO + audit log;合約 redact / 簽署都在內網完成
- 設定:
docker-compose-latest-fat-security.yml+ PostgreSQL + LDAP / SAML
場景 B:客服 / 行政自動化
- 痛點:每天收到 100+ 份掃描 PDF 需要 OCR + 合併 + 蓋章
- 解法:用 Pipeline 功能拖拉建立工作流,或 curl 直接打 REST API
- API 範例:
1curl -X POST http://localhost:8080/api/v1/general/merge-pdfs \ 2 -F "fileInput=@a.pdf" -F "fileInput=@b.pdf" \ 3 -o merged.pdf
場景 C:開發者整合進現有後台
- 痛點:自己重新實作 PDF 處理太貴
- 解法:起一個 backend-only 容器,內部後台直接打 API
- 設定:
docker-compose-unified-backend.yml,外部 frontend 自己做
場景 D:個人桌面取代 Acrobat
- 痛點:Adobe Acrobat 訂閱貴 / 不想雲端傳輸
- 解法:下載 Tauri Desktop 版,完全離線使用
場景 E:批次 OCR 大量歷史掃描檔
- 痛點:歷史檔案上萬份待 OCR
- 解法:Pipeline UI 拖拉「OCR → 壓縮 → 重新命名」 batch job,或直接 cron + curl
6. 資安掃描報告
本節基於對 v2.11.0 之後 commit 的靜態掃描 + 設計層審查,不代表完整滲透測試。 官方有 SECURITY.md 與漏洞回報流程。
6.1 紅黃綠燈
| 項目 | 燈號 | 觀察 |
|---|---|---|
| 程式碼基本衛生 | 🟢 | 無硬編碼密碼 / token;secrets 全走環境變數(${SUPABASE_EDGE_FUNCTION_SECRET:} 等預設空字串) |
| ProcessBuilder 使用 | 🟢 | 僅見於 ExternalAppDepConfig 探測外部 binary 是否存在(List |
| 反射(reflect) | 🟢 | 全部出現在 src/test/(單元測試存取 private field),無 production 反射執行 |
| 預設無登入 | 🟡 | SECURITY_ENABLELOGIN=false 是 demo 預設,正式環境必須改 true;否則任何能連到 :8080 的人都可上傳檔案 |
| H2 DB 多容器共用 | 🟡 | Issue #6395 — H2 不支援多 process 寫入,volume 共享會破壞 admin 認證;生產務必用 PostgreSQL |
| LibreOffice / unoserver 攻擊面 | 🟡 | 多年來 LibreOffice CVE 不少;上傳 .docx / .ppt 會走 LibreOffice 轉檔;建議搭配檔案類型白名單 + sandbox |
| PDFBox 解析未知 PDF | 🟡 | 解析複雜或 malformed PDF 是常見 attack vector;近期 issue #6317(cert-sign 與空白密碼產生 corrupted PDF)顯示 edge case 仍有 |
| 上傳大小限制 | 🟡 | SYSTEM_MAXFILESIZE 預設 100 MB(demo 設定);公開暴露建議下調並加 rate limit |
| 容器以非 root 執行 | 🟢 | 官方 Dockerfile 有切換 user,遵循 OCI 最佳實踐 |
| 依賴更新節奏 | 🟢 | Dependabot 全自動,近一週 10+ 個 bump(idna / requests / ws / protobufjs / spotless / codeql-action) |
| OpenSSF Scorecard | 🟢 | 官方有貼 badge,分數可在 https://scorecard.dev/viewer/?uri=github.com/Stirling-Tools/Stirling-PDF 查 |
| 公開到 Internet | 🔴 | 不建議直接暴露到公網;必須放在 reverse proxy(Caddy / Nginx)後 + IP 白名單 / VPN / SSO + WAF |
6.2 部署建議(生產環境檢查清單)
-
SECURITY_ENABLELOGIN=true一律開啟 - 改用 PostgreSQL(不再用 H2)
- 反向代理(Caddy / Nginx)+ TLS 終結
- IP 白名單 / VPN / Cloudflare Access / 公司 SSO
-
SYSTEM_MAXFILESIZE依實際需求設定,並在反向代理層加 rate limit - 上傳檔案目錄掛 read-only 副本 / 定期掃毒(ClamAV)
- 容器以非 root user 跑、capabilities drop(已是預設)
- 監控
/api/v1/info/statushealthcheck + Prometheus metrics - 訂閱 GitHub Security Advisories
- 每月跟 release(每月 1-2 個 minor)
6.3 攻擊面總結
| 攻擊向量 | 風險 | 緩解 |
|---|---|---|
| 上傳惡意 PDF(PDFBox parser bug) | 中 | sandbox + 檔案大小限制 + 不執行 PDF JS |
| 上傳惡意 Office 檔(LibreOffice CVE) | 中 | 用 ultra-lite image(無 LibreOffice)/ remote unoserver 隔離 |
| 公開未認證 instance 被當免費 PDF API | 高 | SECURITY_ENABLELOGIN=true + 反向代理認證 |
| 多容器共用 H2 → admin 密碼漂移 | 中 | 改 PostgreSQL |
| Dependabot 之外的供應鏈風險 | 低 | OpenSSF Scorecard + SBOM |
7. FAQ
Q1:免費版功能會被閹割嗎?
A:核心 50+ 工具全部在 app/core(open-core 模式),完全免費可用。付費差異在 app/proprietary(SSO / audit log / enterprise support)與 app/saas(managed cloud)。
Q2:可以放心處理機密合約嗎? A:技術上可以(檔案不出機器、預設不送遙測)。但要做到「機密級」需自行加上 §6.2 的所有控制。
Q3:為什麼有時候轉檔失敗?
A:常見是 LibreOffice / unoserver 沒裝(用 ultra-lite image 時)或 crash(issue #6397)。看 logs /logs/stirling-pdf.log 並對照官方 Discord。
Q4:可以橫向擴展嗎? A:可以,但必須先換成 PostgreSQL,因為 H2 不支援多 instance 共享。
Q5:與 Paperless-ngx 差異? A:Paperless 偏「文件管理 + 索引 + 全文搜尋」,Stirling-PDF 偏「PDF 工具集 + 編輯」。兩者互補:Paperless 收進文件 → Stirling 編輯 / OCR / 拆分。
Q6:API 認證怎麼做?
A:開啟 SECURITY_ENABLELOGIN 後,UI 走 session;API 用 JWT bearer token(SECURITY_JWT_* 系列環境變數)。
Q7:可以加自訂工具嗎?
A:可以,見 ADDING_TOOLS.md(6 步驟:Controller → Service → 註冊 → tooltip → 翻譯 → 測試)。
Q8:translations 怎麼貢獻?
A:見 devGuide/HowToAddNewLanguage.md;維護 40+ 語系是專案重要工作流之一。
8. 進階技巧
8.1 用 Pipeline 取代手動操作
UI 的 Pipeline 功能可以把多步驟串成 JSON 工作流,存成 .json 後可重複呼叫,等同 PDF 版 Airflow。
8.2 Headless API 整合 n8n / Zapier
REST API 是標準 multipart/form-data,n8n / Zapier 的 HTTP node 可直接打。範例:
1# OCR 一份掃描檔
2curl -X POST http://stirling:8080/api/v1/misc/ocr-pdf \
3 -F "fileInput=@scan.pdf" \
4 -F "languages=eng,chi_tra" \
5 -o ocr.pdf
8.3 用 ultra-lite image + remote unoserver 拆風險
把 LibreOffice 攻擊面隔離到獨立 unoserver 容器,主 image 用 ultra-lite。範本:docker/embedded/compose/docker-compose-latest-security-remote-uno.yml。
8.4 在 K8s 跑
官方文件提供 Helm chart 與 K8s manifest,PV 掛 /configs / /logs / /tessdata,HPA 設 CPU-based scaling,搭配 PostgreSQL StatefulSet。
8.5 自架 SSO
SECURITY_OAUTH2_* / SECURITY_SAML2_* 系列變數支援 Keycloak / Okta / Azure AD / Google。
9. 整合進其他工作流
| 整合對象 | 做法 |
|---|---|
| AI 知識管線 | docling / markitdown 抽 PDF 文字後丟給 LLM;Stirling-PDF 負責前處理(合併 / OCR / 拆章節) |
| Paperless-ngx | Paperless consume folder → Stirling OCR / split → 回寫 Paperless |
| n8n / Zapier | HTTP node + multipart 直接打 /api/v1/... |
| Nextcloud | Nextcloud Files external app + Stirling API |
| CI / GitHub Actions | runner 內裝 Docker,用 Stirling 預處理測試 fixture |
| 法務簽署流程 | 上傳 → redact → sign → 寄出,全程 audit log |
10. 重點摘要 Checklist
- 確認部署模式(Docker / Desktop / K8s)
- 選擇 image 變體(standard / ultra-lite / fat)
- 設定環境變數(至少:
SECURITY_ENABLELOGIN=true+LANGS+SYSTEM_MAXFILESIZE) - 持久化 volume(
/configs//logs//tessdata//pipeline) - 改用 PostgreSQL(如要多 instance / 生產)
- 放在反向代理 + TLS + SSO / VPN 後
- 訂閱 GitHub Security Advisories
- 規劃月度版本升級節奏(跟著 release notes)
- 文件化內部工作流(Pipeline JSON / API 整合腳本)
- 訂團隊內 PDF 處理 SOP(哪些用 Stirling、哪些用 Adobe)
11. 進一步閱讀
- 官方文件:https://docs.stirlingpdf.com
- API 參考:https://registry.scalar.com/@stirlingpdf/apis/stirling-pdf-processing-api/
- Repo 內:
README.md— 快速起步DeveloperGuide.md— 完整開發者手冊(11 章)ADDING_TOOLS.md— 新增工具的標準流程DATABASE.md— 資料庫設定(H2 vs PostgreSQL)FILE_SHARING.md— 多人協作功能設計SHARED_SIGNING.md— 共享簽署流程SECURITY.md— 漏洞回報流程
- 社群:
- Discord:https://discord.gg/HYmhKj45pU
- GitHub Issues:https://github.com/Stirling-Tools/Stirling-PDF/issues
- 同類比較:
- pdf.js(純前端 viewer)
- Paperless-ngx(文件管理)
- PDF24(線上 SaaS)
- gh-save 摘要:
inbox/2026-05-25-github-Stirling-Tools-Stirling-PDF.md
本文件由 AI-knowledge template gh-tutorial-qd 工作流自動生成(2026-05-25)。基於 v2.11.0 release 後的快照,未來版本可能有差異。
Comments