Skip to main content

Self-Host Stirling PDF: All-in-One PDF Toolkit 2026

·OSSAlt Team
stirling-pdfpdftoolsself-hostingdocker2026

TL;DR

Stirling PDF (GPL 3.0, ~45K GitHub stars, Java/Spring Boot) is a self-hosted PDF manipulation toolkit — a complete replacement for Adobe Acrobat and online tools like ILovePDF or SmallPDF. Merge, split, compress, rotate, OCR, add passwords, sign, convert to/from PDF, extract pages, add watermarks — 50+ PDF operations in one web app. Privacy advantage: your documents never leave your server. Adobe Acrobat Standard costs $155/year; Stirling PDF is free.

Key Takeaways

  • Stirling PDF: GPL 3.0, ~45K stars — 50+ PDF operations, fully self-hosted
  • Privacy: Documents stay on your server — never uploaded to third-party services
  • OCR: Built-in Tesseract OCR makes scanned PDFs searchable
  • Libre Office: Converts Office documents (DOCX, XLSX, PPTX) to/from PDF
  • No file size limits: Process multi-GB PDFs without upload restrictions
  • API: REST API for automating PDF workflows

Operations Available

CategoryOperations
OrganizeMerge, Split, Remove pages, Extract pages, Reorder, Rotate, Scale
ConvertPDF→Word, PDF→HTML, PDF→XML, Word/Excel/PPT→PDF, HTML→PDF, Markdown→PDF
SecurityAdd/Remove password, Add watermark, Redact text, Sign PDF
OptimizeCompress, Grayscale, Remove annotations
OCRMake searchable, Extract text
AdvancedCompare PDFs, Repair, Flatten, Add page numbers, Add image

Part 1: Docker Setup

Without OCR (Smaller)

# docker-compose.yml
services:
  stirling-pdf:
    image: frooodle/s-pdf:latest
    container_name: stirling-pdf
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - stirling_config:/configs
      - stirling_logs:/logs
    environment:
      DOCKER_ENABLE_SECURITY: "false"
      INSTALL_BOOK_AND_ADVANCED_HTML_OPS: "false"
      LANGS: "en_GB"

volumes:
  stirling_config:
  stirling_logs:

With OCR and Office Document Conversion (Full)

services:
  stirling-pdf:
    image: frooodle/s-pdf:latest-fat    # Includes Tesseract + LibreOffice
    container_name: stirling-pdf
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - stirling_config:/configs
      - stirling_logs:/logs
      - stirling_tessdata:/usr/share/tessdata    # OCR language data
    environment:
      DOCKER_ENABLE_SECURITY: "false"
      INSTALL_BOOK_AND_ADVANCED_HTML_OPS: "true"
      LANGS: "en_GB"
      # For Calibre ebook support:
      # INSTALL_BOOK_AND_ADVANCED_HTML_OPS: "true"
docker compose up -d

Visit http://your-server:8080 — no login required by default.


Part 2: HTTPS with Caddy

pdf.yourdomain.com {
    reverse_proxy localhost:8080
}

Part 3: Enable Authentication

By default, Stirling PDF is open. Add login:

environment:
  DOCKER_ENABLE_SECURITY: "true"
  SECURITY_ENABLE_LOGIN: "true"
  SECURITY_INITIALLOGIN_USERNAME: admin
  SECURITY_INITIALLOGIN_PASSWORD: "${ADMIN_PASSWORD}"

Users can be managed via Settings → Users after login.


Part 4: Common Operations

Merge PDFs

  1. Organize → Merge PDFs
  2. Upload multiple files (or drag and drop)
  3. Reorder by dragging
  4. Merge → download combined PDF

Split PDF

  1. Organize → Split PDFs
  2. Upload PDF
  3. Choose: split by page range, split after every N pages, or split at specific pages
  4. Download as ZIP (multiple files) or individual downloads

Compress PDF

  1. Optimize → Compress PDFs
  2. Choose compression level: low / medium / high / very high
  3. Stirling uses Ghostscript for compression — typically 50-80% size reduction

OCR (Make Searchable)

  1. Add OCR → Add Text Layer
  2. Upload scanned PDF
  3. Choose language (English, German, French, etc.)
  4. Download searchable PDF — text is selectable and copyable

Convert DOCX to PDF

  1. Convert → Office Documents to PDFs
  2. Upload .docx, .xlsx, or .pptx
  3. Download as PDF

Requires the -fat image (includes LibreOffice).

Add Password Protection

  1. Security → Add/Change Password on PDF
  2. Set user password (required to open) and/or owner password (required to edit/print)
  3. Choose encryption: 128-bit RC4 or 256-bit AES

Remove Password

  1. Security → Remove PDF Security
  2. Upload password-protected PDF
  3. Enter the current password
  4. Download unlocked PDF

Watermark

  1. Add Watermark
  2. Text watermark: type text, choose position, opacity, angle
  3. Or image watermark: upload image
  4. Preview before downloading

Part 5: Additional OCR Languages

The default image includes English. For other languages:

volumes:
  - stirling_tessdata:/usr/share/tessdata
# Download additional language packs (run once):
docker exec stirling-pdf apt-get install -y \
  tesseract-ocr-deu \   # German
  tesseract-ocr-fra \   # French
  tesseract-ocr-spa \   # Spanish
  tesseract-ocr-jpn \   # Japanese
  tesseract-ocr-chi-sim  # Simplified Chinese

Or pre-download tessdata files:

# Download from https://github.com/tesseract-ocr/tessdata
wget -P /path/to/tessdata/ https://github.com/tesseract-ocr/tessdata/raw/main/deu.traineddata

Part 6: REST API

Automate PDF operations programmatically:

# Merge PDFs via API:
curl -X POST "https://pdf.yourdomain.com/api/v1/general/merge-pdfs" \
  -H "Content-Type: multipart/form-data" \
  -F "fileInput=@file1.pdf" \
  -F "fileInput=@file2.pdf" \
  -o merged.pdf

# Compress a PDF:
curl -X POST "https://pdf.yourdomain.com/api/v1/general/compress-pdf" \
  -H "Content-Type: multipart/form-data" \
  -F "fileInput=@large.pdf" \
  -F "optimizeLevel=2" \
  -o compressed.pdf

# Extract pages (1-3):
curl -X POST "https://pdf.yourdomain.com/api/v1/general/extract-pages" \
  -H "Content-Type: multipart/form-data" \
  -F "fileInput=@document.pdf" \
  -F "pageNumbers=1,2,3" \
  -o extracted.pdf

# OCR a PDF:
curl -X POST "https://pdf.yourdomain.com/api/v1/misc/ocr-pdf" \
  -H "Content-Type: multipart/form-data" \
  -F "fileInput=@scanned.pdf" \
  -F "languages=eng" \
  -o searchable.pdf

Full API docs: https://pdf.yourdomain.com/swagger-ui/index.html


Part 7: Batch Processing

For processing many files at once:

#!/bin/bash
# batch-compress.sh — compress all PDFs in a directory

PDF_DIR="/path/to/pdfs"
API="https://pdf.yourdomain.com/api/v1/general/compress-pdf"

for f in "$PDF_DIR"/*.pdf; do
  base=$(basename "$f" .pdf)
  echo "Compressing: $base"
  curl -s -X POST "$API" \
    -F "fileInput=@$f" \
    -F "optimizeLevel=2" \
    -o "$PDF_DIR/${base}-compressed.pdf"
done
echo "Done"

Part 8: Configuration

# /configs/settings.yml (created on first run)

system:
  defaultLocale: en-US
  googlevisibility: false
  enableAlphaFunctionality: false

ui:
  appName: "My PDF Tools"
  homeDescription: "Self-hosted PDF toolkit"
  appNameNavbar: "PDF Tools"

# Legal / custom footer:
  loginPageMessage: ""

Maintenance

# Update Stirling PDF:
docker compose pull
docker compose up -d

# Logs:
docker compose logs -f stirling-pdf

# Backup config:
tar -czf stirling-config-$(date +%Y%m%d).tar.gz \
  $(docker volume inspect stirling_stirling_config --format '{{.Mountpoint}}')

See all open source document and office tools at OSSAlt.com/categories/productivity.

Comments