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

VolumePurpose
./trainingDataOCR language data (Tesseract)
./extraConfigsCustom configuration files
./logsApplication logs
./customFilesCustom branding, templates

Environment Variables

VariableDefaultDescription
DOCKER_ENABLE_SECURITYfalseEnable user authentication
INSTALL_BOOK_AND_ADVANCED_HTML_OPSfalseInstall Calibre for ebook conversion
LANGSen_GBInterface 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

p}df.yroeuvredrosmea_ipnr.ocxoyms{tirling-pdf:8080

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: