Every time you need to merge two PDFs, compress a large file, or convert a document, you probably end up on some random website. You upload your file, wait for processing, hope they’re not reading your tax returns, and download the result. There’s a better way.
Stirling PDF is a self-hosted, open-source PDF toolkit that handles virtually everything you’d ever need to do with a PDF — merge, split, rotate, compress, convert, OCR, add watermarks, extract images, and dozens more operations. It runs entirely on your own server, so your documents never leave your network.
In this guide, we’ll set up Stirling PDF with Docker, configure it for daily use, and explore the features that make it one of the most popular self-hosted tools in 2026.
Why Self-Host Your PDF Tools?
Before we dive in, here’s why running your own PDF toolkit matters:
- Privacy: Your documents stay on your server. Tax forms, contracts, medical records — none of it touches a third-party service.
- No file size limits: Most online PDF tools cap uploads at 10-50MB. Your server, your rules.
- No usage limits: Merge 500 PDFs at 3am if you want. No daily caps, no premium upsells.
- Speed: Local processing is fast. No upload/download wait times on large files.
- Offline capable: Works on your LAN even if your internet goes down.
Prerequisites
Before starting, you’ll need:
- A server or home lab machine running Linux (Ubuntu, Debian, or similar)
- Docker and Docker Compose installed
- At least 512MB free RAM (1GB recommended for OCR features)
- Basic familiarity with the command line
If you don’t have Docker installed yet, check out our Docker setup guide first.
Quick Start: Deploy Stirling PDF with Docker Compose
Create a directory for your Stirling PDF instance:
mkdir -p ~/docker/stirling-pdf
cd ~/docker/stirling-pdf
Create a docker-compose.yml file:
services:
stirling-pdf:
image: frooodle/s-pdf:latest
container_name: stirling-pdf
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./trainingData:/usr/share/tessdata
- ./extraConfigs:/configs
- ./logs:/logs
- ./customFiles:/customFiles
environment:
- DOCKER_ENABLE_SECURITY=false
- INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false
- LANGS=en_GB
Start the container:
docker compose up -d
That’s it. Open http://your-server-ip:8080 in your browser and you’ll see the Stirling PDF interface ready to go.
Understanding the Configuration
Let’s break down the key settings:
Volumes
| Volume | Purpose |
|---|---|
./trainingData | OCR language data (Tesseract) |
./extraConfigs | Custom configuration files |
./logs | Application logs |
./customFiles | Custom branding, templates |
Environment Variables
| Variable | Default | Description |
|---|---|---|
DOCKER_ENABLE_SECURITY | false | Enable user authentication |
INSTALL_BOOK_AND_ADVANCED_HTML_OPS | false | Install Calibre for ebook conversion |
LANGS | en_GB | Interface language |
Enabling OCR Support
One of Stirling PDF’s killer features is built-in OCR (Optical Character Recognition). This lets you convert scanned documents into searchable, selectable text.
OCR uses Tesseract under the hood. To add language packs, download the trained data files:
mkdir -p trainingData
cd trainingData
# English (included by default, but grab the best quality version)
wget https://github.com/tesseract-ocr/tessdata_best/raw/main/eng.traineddata
# Spanish
wget https://github.com/tesseract-ocr/tessdata_best/raw/main/spa.traineddata
# French
wget https://github.com/tesseract-ocr/tessdata_best/raw/main/fra.traineddata
# German
wget https://github.com/tesseract-ocr/tessdata_best/raw/main/deu.traineddata
Restart the container to pick up the new language files:
docker compose restart
Now when you use the OCR feature, you can select from any installed language.
Enabling User Authentication
If you’re exposing Stirling PDF beyond your local network (or share the server with others), you’ll want to enable authentication:
environment:
- DOCKER_ENABLE_SECURITY=true
- SECURITY_ENABLELOGIN=true
- SECURITY_INITIALLOGIN_USERNAME=admin
- SECURITY_INITIALLOGIN_PASSWORD=your-secure-password-here
After restarting, you’ll see a login page. The admin account can create additional users with different permission levels.
Enabling Ebook Conversion
If you need to convert between ebook formats (EPUB, MOBI) or do advanced HTML-to-PDF conversion, enable the Calibre integration:
environment:
- INSTALL_BOOK_AND_ADVANCED_HTML_OPS=true
Note: This increases the container size significantly (adds ~400MB for Calibre). Only enable it if you actually need ebook conversion.
What Can Stirling PDF Actually Do?
Here’s a rundown of the major feature categories. The web UI organizes them into clean sections:
Page Operations
- Merge PDFs — Combine multiple files into one, drag to reorder
- Split PDF — Extract specific pages or split into chunks
- Rotate pages — Fix sideways scans
- Remove pages — Delete specific pages from a document
- Rearrange pages — Visual drag-and-drop page ordering
Conversion
- Images to PDF — Convert JPG, PNG, TIFF to PDF
- PDF to Images — Extract every page as an image
- HTML to PDF — Render web pages as PDFs
- PDF to Word/Excel/PowerPoint — Office format conversion
- Markdown to PDF — Great for developers
Security
- Add password — Encrypt PDFs with a password
- Remove password — Unlock password-protected files (if you have the password)
- Add watermark — Stamp text or image watermarks
- Sanitize — Remove metadata, JavaScript, and hidden content
- Redact — Black out sensitive information
Advanced
- OCR — Make scanned documents searchable
- Compress — Reduce file size for email or storage
- Flatten — Merge form fields and annotations into the document
- Compare — Visual diff between two PDFs
- Add page numbers — Automatic numbering with customizable format
- Auto-rename — Rename files based on content or metadata
Running Behind a Reverse Proxy
If you’re running Traefik, Caddy, or Nginx as a reverse proxy (and you should be), here’s how to configure access:
Caddy
Nginx
server {
listen 80;
server_name pdf.yourdomain.com;
client_max_body_size 100M;
location / {
proxy_pass http://localhost: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;
}
}
Important: Set client_max_body_size high enough for your largest PDFs. The default Nginx limit of 1MB will block most uploads.
Traefik (Docker Labels)
labels:
- "traefik.enable=true"
- "traefik.http.routers.stirling-pdf.rule=Host(`pdf.yourdomain.com`)"
- "traefik.http.routers.stirling-pdf.entrypoints=websecure"
- "traefik.http.routers.stirling-pdf.tls.certresolver=letsencrypt"
API Access
Stirling PDF includes a full REST API, which means you can automate PDF operations from scripts or other tools. The API documentation is built into the app at /swagger-ui/index.html.
Here’s an example using curl to merge two PDFs:
curl -X POST "http://localhost:8080/api/v1/general/merge-pdfs" \
-F "[email protected]" \
-F "[email protected]" \
-o merged.pdf
Compress a PDF:
curl -X POST "http://localhost:8080/api/v1/general/compress-pdf" \
-F "[email protected]" \
-F "optimizeLevel=3" \
-o compressed.pdf
This opens up powerful automation — imagine a cron job that compresses every PDF dropped into a folder, or an n8n workflow that OCRs incoming scanned documents automatically.
Performance Tuning
For heavier workloads, you can allocate more resources:
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 512M
If you process many OCR documents, consider pinning more CPU:
deploy:
resources:
limits:
cpus: '2.0'
Troubleshooting
Container won’t start
Check logs with docker compose logs stirling-pdf. The most common issue is port 8080 already being in use. Change the port mapping (e.g., 8085:8080).
OCR not working
Make sure .traineddata files are in the trainingData directory and the container has been restarted. Check file permissions — the container needs read access.
Large files timing out
If you’re behind a reverse proxy, increase timeout values. For Nginx, add proxy_read_timeout 300s; to your location block.
High memory usage during OCR
OCR on large documents is memory-intensive. If the container gets killed, increase the memory limit in your compose file or process fewer pages at a time.
Authentication locked out
If you forget your admin password, stop the container, delete the ./extraConfigs/users.yaml file, and restart. You’ll be back to the initial login credentials.
Updating Stirling PDF
Staying current is easy:
cd ~/docker/stirling-pdf
docker compose pull
docker compose up -d
Your configuration and data persist in the mounted volumes, so updates are non-destructive.
Conclusion
Stirling PDF is one of those tools that immediately earns its place in any homelab. It replaces a dozen bookmarked web tools with a single, private, fast interface. The setup takes five minutes, it handles everything from basic merges to OCR and format conversion, and your documents never leave your network.
For most users, the quick-start compose file is all you need. Add OCR languages if you work with scanned documents, enable authentication if others access your server, and point a reverse proxy at it for HTTPS access from anywhere.
Once you start using it, you’ll wonder why you ever uploaded PDFs to random websites.
Useful links:
- Stirling PDF GitHub
- Official Documentation
- API Documentation (after install)