Stirling-PDF is an open-source, web-based PDF toolkit that you host yourself. It covers the everyday jobs people usually upload to random websites: merging, splitting, rotating, compressing, converting (PDF ↔ images, Office, HTML, Markdown), OCR, watermarks, signatures, redaction, page reordering and metadata editing. Files are processed on your server and not stored afterwards, so sensitive documents never touch a third-party service.
What it can do
| Category | Examples |
|---|---|
| Organise | Merge, split, reorder, rotate, remove pages, multi-page layout |
| Convert | PDF ↔ images, Office ↔ PDF (via LibreOffice), HTML/URL/Markdown → PDF, PDF → PDF/A |
| Optimise | Compress, repair, remove blank pages |
| Security | Add/remove passwords, permissions, redaction, sanitise (remove scripts, metadata) |
| Text | OCR (Tesseract/OCRmyPDF) to make scans searchable, extract images |
| Sign | Draw, type or certificate-based signatures, stamps, watermarks |
| Automate | Pipelines (multi-step jobs) and a REST API |
Requirements
- 1–2 vCPU and 2 GB RAM for occasional use.
- OCR and Office conversions are CPU-heavy. Give it more cores for large scanned documents, or for several users.
- The “fat” image (with LibreOffice, OCR languages and fonts) is a few GB, so plan disk space.
Install with Docker
# /opt/stirling-pdf/compose.yaml
services:
stirling-pdf:
image: stirlingtools/stirling-pdf:latest
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
environment:
DOCKER_ENABLE_SECURITY: "true" # enables the login system
SECURITY_ENABLELOGIN: "true"
LANGS: en_GB
SYSTEM_MAXFILESIZE: 200 # MB
volumes:
- ./tessdata:/usr/share/tessdata # OCR language data
- ./configs:/configs # settings.yml, database
- ./logs:/logs
cd /opt/stirling-pdf && docker compose up -d
Image tags vary by edition (full, standard, ultra-lite). Pick the full image if you need Office conversion and OCR, and check the docs for current tag names and variables.
OCR languages: the image includes English. Add others by placing Tesseract .traineddata files (for example chi_sim, jpn, deu) in ./tessdata.
Login and users
With security enabled, the first start creates a default admin account (shown in the docs, typically admin / stirling). You’re asked to change the password on first login. Add users in the admin settings. Optional SSO via OAuth2/OIDC is available.
Without login, anyone who can reach the site can use your CPU. Only run it without authentication on a private network or VPN.
Nginx with HTTPS
server {
server_name pdf.example.com;
client_max_body_size 200M; # match SYSTEM_MAXFILESIZE
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 600s; # long OCR/conversion jobs
}
# listen 443 ssl; certbot --nginx -d pdf.example.com
}
See Nginx reverse proxy and Let’s Encrypt. If you get “413 Request Entity Too Large”, see fix 413 errors.
OCR scanned documents
Choose OCR / Cleanup scans, and select the language. Options include deskew, cleaning, and “skip text pages”. The result is a searchable PDF with a hidden text layer, ideal before archiving to Paperless-ngx or Nextcloud.
API and pipelines
Every tool is also an API endpoint (Swagger docs at /swagger-ui/index.html):
curl -X POST https://pdf.example.com/api/v1/general/merge-pdfs \
-H "X-API-KEY: $KEY" \
-F "[email protected]" -F "[email protected]" -o merged.pdf
Pipelines chain operations (for example OCR → compress → add watermark) and can watch a folder for automatic processing.
Privacy and resources
- Uploaded files are processed in temporary storage and deleted. They aren’t kept in a library.
- Limit file size, and watch CPU during OCR. See htop.
- Keep the container updated. It bundles many document-parsing libraries, and those get security fixes. See updating self-hosted apps.
Quick reference
| Item | Value |
|---|---|
| Port | 8080 |
| Enable login | DOCKER_ENABLE_SECURITY=true |
| Upload size | SYSTEM_MAXFILESIZE + Nginx client_max_body_size |
| OCR languages | .traineddata files in /usr/share/tessdata |
| API docs | /swagger-ui/index.html |
Related: OnlyOffice Docs and Nextcloud.