Jesse A. Green / notebook

Stirling-PDF Administrator & Developer Guide

Generated May 2026 from Stirling-Tools/Stirling-PDF at 79f4748

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Stirling-PDF is a self-hosted, enterprise-capable PDF manipulation platform built on a multi-module architecture spanning Java (Spring Boot), TypeScript (React/Mantine), Rust (Tauri), and Python (FastAPI). This guide covers every operational and development concern for administrators, DevOps engineers, and contributors working with Stirling-PDF version 2.9.2.


1. Architecture Overview

Stirling-PDF follows a modular monorepo structure with four distinct runtime components that can be deployed together or independently.

1.1 Component Map

┌─────────────────────────────────────────────────────────────┐
│                     Stirling-PDF v2.9.2                      │
├──────────────┬──────────────┬───────────────┬───────────────┤
│   Backend    │   Frontend   │    Desktop    │   AI Engine   │
│ Spring Boot  │ React/Vite   │  Tauri/Rust   │ Python/FastAPI│
│  4.0.5       │ Mantine UI   │              │  pydantic-ai  │
│  Java 21     │ TypeScript   │              │              │
├──────────────┼──────────────┼───────────────┼───────────────┤
│  app/common  │ frontend/src │ frontend/    │ engine/src/   │
│  app/core    │   /core      │  src-tauri/  │  stirling/    │
│  app/        │   /proprietary│             │   api/        │
│  proprietary │   /saas      │              │   agents/     │
│              │   /desktop   │              │              │
└──────────────┴──────────────┴───────────────┴───────────────┘

1.2 Backend Modules

The Spring Boot backend is split into three Gradle subprojects:

Module Path Purpose
common app/common/ Shared models, configuration classes, annotations, cross-cutting services (TaskManager, FileStorage, EndpointConfiguration)
core app/core/ All PDF operation controllers (19 controller files), core configuration (19 config files), PDF manipulation via Apache PDFBox 3.0.7
proprietary app/proprietary/ Enterprise features: OAuth2, SAML2, SSO, user/role management, audit logging, workflows. Licensed under Stirling PDF User License

The application entry point is stirling.software.SPDF.SPDFApplication. The embedded servlet container is not Tomcat — the build explicitly excludes spring-boot-starter-tomcat in favor of Jetty/Undertow.

1.3 Frontend Architecture

The React frontend uses Vite as the build tool and is organized into four feature domains:

Domain Path Contents
core frontend/src/core/ 47 service files, 49 utility files, page editor with undo/redo command pattern, PDFium WASM rendering, i18n (40+ locales)
proprietary frontend/src/proprietary/ Auth flows, Stripe checkout, workflow builder, enterprise configuration UI
saas frontend/src/saas/ SaaS deployment: onboarding, billing, PostHog analytics
desktop frontend/src/desktop/ Tauri bridge services, backend health monitoring, connection mode management, operation routing

Note

The frontend uses PDFium compiled to WebAssembly for client-side PDF rendering and manipulation. This means many operations execute entirely in the browser without round-tripping to the backend.

1.4 Desktop Application (Tauri)

The desktop app wraps the React frontend in a native Rust shell (frontend/src-tauri/). Tauri commands expose:

  • Auth: save/get/clear tokens for enterprise auth
  • Backend management: spawn, monitor, and manage a local backend process
  • Connection modes: local backend, remote server, or hybrid
  • File handling: native file dialogs, drag-and-drop, default PDF handler registration
  • Native print: OS-level print integration
  • Platform detection: Windows/macOS/Linux-specific behavior

A Windows thumbnail handler DLL (stirling_thumbnail_handler.dll) implements the COM IThumbnailProvider interface, enabling PDF preview thumbnails directly in Windows Explorer. A provisioner tool supports enterprise deployment by locking the server URL in configuration.

1.5 AI Engine

The Python FastAPI service (engine/src/stirling/api/app.py) provides AI-powered PDF operations using pydantic-ai:

Agent Role
OrchestratorAgent Routes user natural-language requests to the correct tool/agent
PdfEditAgent AI-guided PDF editing based on user instructions
PdfQuestionAgent Answers questions about PDF content
UserSpecAgent Drafts and revises user specifications from requirements
ExecutionPlanningAgent Plans multi-step PDF operation sequences
MathAuditorAgent Audits financial/math PDFs, verifies ledger entries

API routes: /draft, /revise, /next-action, /examine, /deliberate, /orchestrate, /pdf_edit, /pdf_questions, /health.

1.6 Dependency Stack

Layer Technology Version
JVM Java 21 (source/target), 25 (compilation toolchain)
Framework Spring Boot 4.0.5
PDF manipulation Apache PDFBox 3.0.7
Cryptography BouncyCastle 1.83
Image I/O TwelveMonkeys imageio 3.13.1
Code generation Lombok 1.18.44
SAML Spring Security SAML 7.0.4
SAML (impl) OpenSAML 5.2.1
Markdown Commonmark 0.28.0
Frontend framework React + Mantine UI —
Frontend build Vite —
Frontend routing React Router —
Frontend i18n i18next —
Desktop Tauri —
AI runtime FastAPI + pydantic-ai —

2. Requirements & Prerequisites

2.1 Hardware Requirements

Deployment CPU RAM Disk
Ultra-lite (Java-only ops) 1 core 512 MB 500 MB
Standard (with external tools) 2 cores 2 GB 2 GB
Fat (all dependencies) 2+ cores 4 GB 5 GB
With AI engine 2+ cores 4+ GB 6 GB

2.2 Software Requirements

For Docker deployment (recommended):

  • Docker Engine 20.10+
  • Docker Compose v2

For bare-metal / development:

  • Java 21 JDK (compilation requires Java 25 toolchain)
  • Node.js (for frontend build)
  • Gradle (wrapper included)
  • Optional external tools: LibreOffice, qpdf, Ghostscript, Tesseract OCR, OpenCV, Python 3.x, unoconvert

Important

The fat Docker image bundles all external tools. The standard image requires you to install LibreOffice, Tesseract, and other CLI tools separately if you need endpoints that depend on them. The ultra-lite image intentionally excludes all external dependencies.


3. Configuration Mastery

3.1 settings.yml

The primary configuration file is mounted at /configs/settings.yml inside the container. It controls all runtime behavior. Configuration keys map to Spring properties via relaxed binding.

3.2 Environment Variables — Complete Reference

All configuration can be set via environment variables, which override settings.yml values.

System Configuration

Variable Default Description
SYSTEM_DEFAULTLOCALE en-US Default UI language. Supports 40+ locales
SYSTEM_MAXFILESIZE 100 Maximum upload file size in megabytes
SYSTEM_ROOTURIPATH (empty) Base URI path for reverse proxy deployments (e.g., /stirling-pdf)
SYSTEM_GOOGLEVISIBILITY false When true, allows search engine indexing via robots.txt
SYSTEM_ENABLEMOBILESCANNER (unset) Enables mobile document scanner via WebRTC camera access

Security Configuration

Variable Default Description
DOCKER_ENABLE_SECURITY false Master switch for security features (OAuth2, SAML2, user management)
SECURITY_ENABLELOGIN false Enables the login page and session-based authentication
SECURITY_CUSTOMGLOBALAPIKEY (unset) Sets a global API key accepted via X-API-KEY header for all requests

UI Configuration

Variable Default Description
UI_APPNAME Stirling-PDF Application name displayed in the UI
UI_HOMEDESCRIPTION (unset) Custom homepage description text
UI_APPNAMENAVBAR (unset) Custom name in the navigation bar (overrides UI_APPNAME in navbar only)

Container & Process Configuration

Variable Default Description
MODE BOTH Container operating mode: BOTH (full stack), FRONTEND (UI only), BACKEND (API only)
BACKEND_INTERNAL_PORT 8081 Internal backend port when MODE=BOTH
VITE_API_BASE_URL (unset) Backend URL when running frontend-only (MODE=FRONTEND)
PUID 1000 Process user ID inside container
PGID 1000 Process group ID inside container
UMASK 022 File creation mask
JAVA_CUSTOM_OPTS (unset) Additional JVM flags passed to the Java process
STIRLING_JVM_PROFILE balanced JVM tuning profile: balanced (G1GC) or performance (Shenandoah GC)
FAT_DOCKER false Set true when using the fat Docker image to enable all tool-dependent endpoints

Feature Toggles

Variable Default Description
DISABLE_ADDITIONAL_FEATURES false When true, disables all endpoints requiring external CLI tools
ENDPOINTS_GROUPS_TO_REMOVE (unset) Comma-separated list of endpoint groups to disable (e.g., CLI,Python,OpenCV)
METRICS_ENABLED true Enables Prometheus-compatible metrics endpoint
SHOW_SURVEY (unset) Shows feedback survey prompt in the UI

OCR & Language Configuration

Variable Default Description
TESSERACT_LANGS (unset) Comma-separated Tesseract OCR language codes to install (e.g., eng,fra,deu)
LANGS (unset) Supported UI languages

Storage Configuration

Variable Default Description
STORAGE_LOCAL_BASEPATH (unset) Base filesystem path for local file storage (enterprise feature)

LibreOffice / UNO Server Configuration

Variable Default Description
PROCESS_EXECUTOR_AUTO_UNO_SERVER true Automatically starts a local UNO server for LibreOffice operations
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_N_HOST (unset) Hostname of remote UNO server endpoint (N = 0, 1, 2, ...)
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_N_PORT 2003 Port for remote UNO server endpoint
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_N_HOST_LOCATION (unset) Set to remote for remote UNO servers
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_N_PROTOCOL http Protocol for UNO server communication
PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT (unset) Maximum concurrent LibreOffice conversion sessions

AI Engine Configuration

Variable Default Description
STIRLING_SMART_MODEL (unset) AI model for complex reasoning tasks (e.g., gpt-4)
STIRLING_FAST_MODEL (unset) AI model for quick tasks (e.g., gpt-3.5-turbo)
STIRLING_SMART_MODEL_MAX_TOKENS (unset) Max output tokens for smart model
STIRLING_FAST_MODEL_MAX_TOKENS (unset) Max output tokens for fast model
STIRLING_LOG_LEVEL (unset) Engine log level
STIRLING_LOG_FILE (unset) Engine log file path
STIRLING_POSTHOG_ENABLED (unset) Enable PostHog telemetry in AI engine
STIRLING_POSTHOG_API_KEY (unset) PostHog project API key
STIRLING_POSTHOG_HOST (unset) PostHog instance URL

Tip

For resource-constrained environments, set STIRLING_JVM_PROFILE=balanced and PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT=1 to prevent LibreOffice from consuming excessive memory during concurrent conversions.

3.3 Volume Mounts

Container Path Purpose Required
/configs settings.yml and configuration files Recommended
/logs Application log output Recommended
/usr/share/tessdata Tesseract OCR language data files Only for OCR
/customFiles UI customization assets (logos, CSS overrides) Optional
/pipeline Pipeline/automation configuration files Optional
/tmp/stirling-pdf Shared temp directory for remote UNO server operations Only for remote UNO

4. Deployment

4.1 Docker Images

Stirling-PDF provides four Dockerfile variants targeting different use cases:

Variant Dockerfile Size External Tools Use Case
Standard Dockerfile ~800 MB Some (configurable) General purpose
Fat Dockerfile.fat ~2.5 GB All bundled Full feature set, no external deps to manage
Ultra-lite Dockerfile.ultra-lite ~300 MB None Java-only PDF operations, minimal footprint
Unified Dockerfile.unified Varies Configurable Split frontend/backend or combined via MODE env var

4.2 Standard Deployment (Docker Compose)

version: "3.8"
services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:latest
    ports:
      - "8080:8080"
    volumes:
      - ./configs:/configs
      - ./logs:/logs
      - ./customFiles:/customFiles
    environment:
      - DOCKER_ENABLE_SECURITY=false
      - SYSTEM_MAXFILESIZE=100
      - SYSTEM_DEFAULTLOCALE=en-US
    restart: unless-stopped

4.3 Fat Docker Deployment

version: "3.8"
services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:latest-fat
    ports:
      - "8080:8080"
    volumes:
      - ./configs:/configs
      - ./logs:/logs
      - ./tessdata:/usr/share/tessdata
      - ./pipeline:/pipeline
    environment:
      - FAT_DOCKER=true
      - TESSERACT_LANGS=eng,fra,deu,spa
      - SYSTEM_MAXFILESIZE=500
    restart: unless-stopped

Note

The fat image bundles LibreOffice, Tesseract, qpdf, Ghostscript, OpenCV, and Python. Set FAT_DOCKER=true so the endpoint configuration system knows all tool dependencies are satisfied.

4.4 Ultra-lite Deployment

version: "3.8"
services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:latest-ultra-lite
    ports:
      - "8080:8080"
    volumes:
      - ./configs:/configs
    environment:
      - DISABLE_ADDITIONAL_FEATURES=true
    restart: unless-stopped

The ultra-lite image supports only Java-native PDF operations: merge, split, rotate, rearrange, remove pages, add watermark, encrypt/decrypt, metadata editing, flatten, and similar operations that use PDFBox directly without external CLI tools.

4.5 Unified Container — Split Frontend/Backend

The unified Dockerfile supports three operating modes via the MODE environment variable:

Mode: BOTH (default) — runs frontend and backend in a single container:

services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:unified
    environment:
      - MODE=BOTH
      - BACKEND_INTERNAL_PORT=8081
    ports:
      - "8080:8080"

Mode: FRONTEND — serves only the React UI, proxying API calls to a separate backend:

services:
  frontend:
    image: stirlingtools/stirling-pdf:unified
    environment:
      - MODE=FRONTEND
      - VITE_API_BASE_URL=http://backend:8080
    ports:
      - "3000:3000"

Mode: BACKEND — runs only the Spring Boot API:

services:
  backend:
    image: stirlingtools/stirling-pdf:unified
    environment:
      - MODE=BACKEND
    ports:
      - "8080:8080"
    volumes:
      - ./configs:/configs
      - ./logs:/logs

Full split deployment example:

version: "3.8"
services:
  backend:
    image: stirlingtools/stirling-pdf:unified
    environment:
      - MODE=BACKEND
      - DOCKER_ENABLE_SECURITY=true
      - SECURITY_ENABLELOGIN=true
    ports:
      - "8080:8080"
    volumes:
      - ./configs:/configs
      - ./logs:/logs
      - ./tessdata:/usr/share/tessdata

  frontend:
    image: stirlingtools/stirling-pdf:unified
    environment:
      - MODE=FRONTEND
      - VITE_API_BASE_URL=http://backend:8080
    ports:
      - "3000:3000"
    depends_on:
      - backend

Important

When using MODE=FRONTEND, the VITE_API_BASE_URL must be set at build time or via the unified container's entrypoint script. This URL is baked into the frontend JavaScript bundle. Changing it requires a container restart.

4.6 Remote UNO Server (Scalable LibreOffice)

For high-throughput document conversion, deploy LibreOffice as remote UNO servers to distribute the load:

version: "3.8"
services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:latest
    environment:
      - PROCESS_EXECUTOR_AUTO_UNO_SERVER=false
      - PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST=uno-server-1
      - PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_PORT=2003
      - PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST_LOCATION=remote
      - PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_PROTOCOL=http
      - PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST=uno-server-2
      - PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_PORT=2003
      - PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST_LOCATION=remote
      - PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_PROTOCOL=http
    volumes:
      - shared-tmp:/tmp/stirling-pdf
    ports:
      - "8080:8080"

  uno-server-1:
    image: libreoffice-uno-server:latest
    volumes:
      - shared-tmp:/tmp/stirling-pdf

  uno-server-2:
    image: libreoffice-uno-server:latest
    volumes:
      - shared-tmp:/tmp/stirling-pdf

volumes:
  shared-tmp:

Warning

Remote UNO servers require a shared /tmp/stirling-pdf volume between the Stirling-PDF container and all UNO server containers. Without this shared filesystem, file-to-pdf and other LibreOffice-dependent conversions will fail silently because the UNO server cannot access the temporary files created by Stirling-PDF.

Key configuration:

  • Set PROCESS_EXECUTOR_AUTO_UNO_SERVER=false to disable the local UNO server
  • Configure each remote endpoint with incrementing index (_0_, _1_, etc.)
  • Set HOST_LOCATION=remote for each remote endpoint
  • Use PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT to cap concurrent sessions per server

4.7 Reverse Proxy Configuration

When deploying behind a reverse proxy (Nginx, Traefik, Caddy), set SYSTEM_ROOTURIPATH to match the proxy's path prefix.

Nginx example (subpath):

location /stirling-pdf/ {
    proxy_pass http://stirling-pdf: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;
    client_max_body_size 100M;  # Match SYSTEM_MAXFILESIZE
}

With environment: SYSTEM_ROOTURIPATH=/stirling-pdf

Traefik example (subdomain):

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.stirling.rule=Host(`pdf.example.com`)"
  - "traefik.http.routers.stirling.tls.certresolver=letsencrypt"
  - "traefik.http.services.stirling.loadbalancer.server.port=8080"

4.8 Health Check

The container health check endpoint:

curl -f http://localhost:8080${SYSTEM_ROOTURIPATH:-''}/api/v1/info/status | grep -q 'UP'

Docker Compose health check configuration:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/info/status"]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 60s

5. Endpoint Configuration System

The EndpointConfiguration class (in app/common) is the central mechanism for controlling which PDF operations are available at runtime. It evaluates three factors: explicit configuration, external tool availability, and group membership.

5.1 Functional Groups

Endpoints are organized into functional groups. Disabling a group disables all its member endpoints:

Group Endpoints Count
PageOps remove-pages, merge-pdfs, split-pages, rearrange-pages, rotate-pdf, multi-page-layout, booklet-imposition, scale-pages, crop, pdf-to-single-page, auto-split-pdf, split-by-size-or-count, overlay-pdf, split-pdf-by-sections, split-pdf-by-chapters, add-page-numbers, extract-pages 17
Convert pdf-to-img, img-to-pdf, pdf-to-pdfa, file-to-pdf, pdf-to-word, pdf-to-presentation, pdf-to-text, pdf-to-html, pdf-to-xml, html-to-pdf, url-to-pdf, markdown-to-pdf, pdf-to-csv, pdf-to-markdown, eml-to-pdf, pdf-to-epub, pdf-to-vector, vector-to-pdf, pdf-to-video, cbz-to-pdf, pdf-to-cbz, pdf-to-json, json-to-pdf, pdf-to-rtf 24
Security add-password, remove-password, change-permissions, add-watermark, cert-sign, remove-cert-sign, sanitize-pdf, timestamp-pdf, auto-redact, validate-signature, add-stamp, unlock-pdf-forms, redact, verify-pdf, sign 15
Other ocr-pdf, extract-images, update-metadata, flatten, remove-blanks, remove-annotations, get-info-on-pdf, add-attachments, replace-invert-pdf, edit-table-of-contents, text-editor-pdf, add-image, compare, view-pdf, multi-tool, fields, modify-fields, delete-fields, fill 19
Advance compress-pdf, extract-image-scans, repair, auto-rename, scanner-effect, overlay-pdf, adjust-contrast 7
Automation handleData, automate, pipeline 3
DeveloperTools show-javascript 1
DeveloperDocs dev-api-docs, dev-folder-scanning-docs, dev-sso-guide-docs, dev-airgapped-docs 4

5.2 Tool Groups (External Dependencies)

Each tool group maps endpoints to the external binary they require:

Tool Group Required Binary Dependent Endpoints
CLI qpdf, Ghostscript, etc. compress-pdf, extract-image-scans, repair, pdf-to-pdfa, file-to-pdf, pdf-to-word, pdf-to-presentation, pdf-to-html, pdf-to-xml, ocr-pdf, html-to-pdf, url-to-pdf, pdf-to-rtf
Python Python 3.x extract-image-scans, html-to-pdf, url-to-pdf, file-to-pdf
OpenCV OpenCV libraries extract-image-scans
LibreOffice LibreOffice (soffice) file-to-pdf, pdf-to-word, pdf-to-presentation, pdf-to-rtf, pdf-to-html, pdf-to-xml, pdf-to-pdfa
Unoconvert unoconvert file-to-pdf (alternative to LibreOffice)
Java Built-in (JVM) 50+ endpoints — no external dependency

5.3 Disable Reasons

When an endpoint is unavailable, the system reports one of three reasons:

Reason Meaning
CONFIG Explicitly disabled via settings.yml or ENDPOINTS_GROUPS_TO_REMOVE
DEPENDENCY Required external tool is not installed or not found on PATH
UNKNOWN Disabled for an unidentified reason

5.4 Endpoint Alternatives

Some endpoints support multiple backends. For example, file-to-pdf can use either LibreOffice or Unoconvert. If one tool is missing, the system falls back to the alternative if available.

5.5 Disabling Endpoints

Disable entire functional groups:

# In settings.yml
endpoints:
  groupsToRemove:
    - CLI
    - Python

Or via environment variable:

ENDPOINTS_GROUPS_TO_REMOVE=CLI,Python

Disable all external-tool features at once:

DISABLE_ADDITIONAL_FEATURES=true

Disable individual endpoints in settings.yml:

endpoints:
  disabled:
    - ocr-pdf
    - compress-pdf

6. Security

6.1 Authentication Modes

Stirling-PDF supports multiple authentication mechanisms, all gated behind the DOCKER_ENABLE_SECURITY=true master switch:

Mode Module Configuration
Local login proprietary SECURITY_ENABLELOGIN=true — session-based username/password auth
OAuth2 proprietary Spring Security OAuth2 client configuration
SAML2 SSO proprietary Spring Security SAML 7.0.4 + OpenSAML 5.2.1
API key core/proprietary X-API-KEY header — per-user or global (SECURITY_CUSTOMGLOBALAPIKEY)
MFA proprietary TOTP-based multi-factor authentication

Caution

Setting SECURITY_CUSTOMGLOBALAPIKEY creates a single shared API key for all API access. This is convenient for automation but bypasses per-user audit trails. In production, prefer per-user API keys issued through the user management system.

6.2 CSRF Protection

Spring Security CSRF protection is enabled by default when security is active. API endpoints that accept the X-API-KEY header bypass CSRF checks (they are stateless by nature).

6.3 User & Role Management

The proprietary module provides:

  • User creation, modification, deletion
  • Role-based access control
  • Session management (timeout, concurrent session limits)
  • Audit logging of user actions

6.4 Security Hardening Checklist

[ ] Set DOCKER_ENABLE_SECURITY=true
[ ] Enable login: SECURITY_ENABLELOGIN=true
[ ] Configure OAuth2 or SAML2 for SSO
[ ] Set per-user API keys (avoid global key in production)
[ ] Enable MFA for admin accounts
[ ] Set SYSTEM_MAXFILESIZE to prevent abuse
[ ] Deploy behind reverse proxy with TLS
[ ] Set SYSTEM_GOOGLEVISIBILITY=false to prevent indexing
[ ] Mount /configs read-only if settings won't change at runtime
[ ] Review audit logs regularly

7. Operations

7.1 JVM Tuning

Two JVM profiles are available via STIRLING_JVM_PROFILE:

Profile GC Algorithm Best For
balanced (default) G1GC General workloads, predictable pause times
performance Shenandoah GC Low-latency requirements, large heaps

Additional tuning via JAVA_CUSTOM_OPTS:

# Example: increase heap for large PDF processing
JAVA_CUSTOM_OPTS="-Xmx4g -Xms2g -XX:+HeapDumpOnOutOfMemoryError"

7.2 Logging

Application logs are written to the /logs volume mount. Configure log levels via Spring Boot properties in settings.yml or environment variables.

For the AI engine, use STIRLING_LOG_LEVEL and optionally STIRLING_LOG_FILE.

7.3 Metrics

When METRICS_ENABLED=true (default), Stirling-PDF exposes Prometheus-compatible metrics. Integrate with Grafana for dashboarding:

# prometheus.yml scrape config
- job_name: 'stirling-pdf'
  metrics_path: '/actuator/prometheus'
  static_configs:
    - targets: ['stirling-pdf:8080']

7.4 Backup & Restore

Critical data to back up:

Path Contents Frequency
/configs/settings.yml All runtime configuration On change
/configs/ User database (if security enabled) Daily
/customFiles/ UI branding assets On change
/pipeline/ Automation pipeline definitions On change
/usr/share/tessdata/ OCR language data On change

7.5 Scaling Considerations

Horizontal scaling is supported via the unified container's split mode:

                    ┌─── Frontend (MODE=FRONTEND) ──┐
Load Balancer ──────┤                                ├──► Backend Pool
                    └─── Frontend (MODE=FRONTEND) ──┘     (MODE=BACKEND)
                                                          ├── instance-1
                                                          ├── instance-2
                                                          └── instance-3

Tip

LibreOffice is the primary bottleneck in high-throughput deployments. Use remote UNO servers (Section 4.6) to scale document conversion independently from the core PDF operations. Set PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT to prevent a single instance from being overwhelmed.

7.6 OCR Language Management

Tesseract OCR languages are installed via TESSERACT_LANGS:

# Install multiple languages
TESSERACT_LANGS=eng,fra,deu,spa,ita,por,jpn,chi_sim,chi_tra,kor,ara

# Mount custom/additional traineddata files
volumes:
  - ./tessdata:/usr/share/tessdata

Language data files (.traineddata) can be downloaded from the tessdata repository and placed in the mounted volume.


8. Developer Reference

8.1 Build System

The project uses Gradle with the Spring Boot plugin:

# Build everything
./gradlew build

# Build backend only
./gradlew :app:core:build

# Run locally
./gradlew bootRun

# Run with specific profile
./gradlew bootRun --args='--spring.profiles.active=dev'

Build configuration:

  • Java source/target: Java 21
  • Compilation toolchain: Java 25
  • Code formatter: Spotless (google-java-format 1.28.0)
  • Code coverage: JaCoCo
  • Static analysis: SonarQube integration
  • License compliance: dependency-license-report plugin

Version sync: The syncAppVersion Gradle task synchronizes the version number across tauri.conf.json and simulation configuration files.

8.2 Frontend Build

cd frontend

# Install dependencies
npm install

# Development server
npm run dev

# Production build
npm run build

# Run tests
npm run test        # Vitest unit tests
npm run test:e2e    # Playwright E2E tests

8.3 AI Engine Development

cd engine

# Install dependencies
pip install -r requirements.txt

# Run locally
uvicorn stirling.api.app:app --reload --port 8000

# Run tests
pytest tests/

8.4 Code Formatting

Spotless enforces google-java-format 1.28.0:

# Check formatting
./gradlew spotlessCheck

# Auto-fix formatting
./gradlew spotlessApply

Note

The Spotless check runs as part of the build pipeline. Pull requests with formatting violations will fail CI. Run spotlessApply before committing.


9. Module Reference

9.1 Backend — app/common

Shared library consumed by both core and proprietary:

Class / Service Purpose
EndpointConfiguration Runtime endpoint availability management (groups, tools, alternatives)
TaskManager Manages async task execution and progress tracking
FileStorage Abstraction over file storage backends
Annotation classes Custom annotations for endpoint metadata, validation
Model classes Shared DTOs and domain models

9.2 Backend — app/core

The core module contains all PDF operation implementations:

Controllers (app/core/src/main/java/stirling/software/SPDF/controller/api/): 19 controller files totaling ~201K characters of endpoint logic. Controllers are organized by functional domain (page operations, conversions, security, etc.) and delegate to service classes that use PDFBox for manipulation.

Configuration (app/core/.../config/): 19 configuration files handling Spring context setup, bean definitions, security filter chains, CORS, multipart file upload limits, and static resource serving.

Entry Point: stirling.software.SPDF.SPDFApplication — the @SpringBootApplication main class.

9.3 Backend — app/proprietary

Enterprise features under separate license:

Domain Contents
Security OAuth2 client configuration, SAML2 service provider, SSO flow management
User management User CRUD, role assignment, session management, MFA enrollment
Storage Enterprise file storage backends
Workflows Multi-step PDF processing workflows
Audit Action logging, compliance reporting

9.4 Frontend Services

Service Module Purpose
AutomationStorage core Persist and retrieve automation/pipeline configurations
DocumentManipulationService core High-level document manipulation orchestration
EnhancedPDFProcessingService core Advanced PDF processing with progress tracking
FileAnalyzer core Analyze uploaded files (type detection, validation)
FileProcessingService core File upload, processing pipeline, result download
FileStorageService core Client-side file storage (IndexedDB)
GoogleDrivePickerService core Google Drive integration for file import
IndexedDBManager core IndexedDB wrapper for persistent browser storage
PDFExportService core Export PDFs in various formats
PDFProcessingService core Core PDF operations via PDFium WASM
PdfiumDocument / PdfiumPage / PdfiumFont / PdfiumImage core PDFium WASM bindings for client-side rendering
PreferencesService core User preference management
ProcessingCache core Cache intermediate processing results
SignatureStorageService core Store and manage digital signature data
ThumbnailGenerationService core Generate PDF page thumbnails
UpdateService core Check for application updates
ZipFileService core ZIP file creation and extraction
UndoManager core Undo/redo stack for page editor

Page Editor Commands (command pattern):

Command Operation
RotatePageCommand Rotate individual pages
DeletePagesCommand Remove pages from document
ReorderPagesCommand Drag-and-drop page reordering
SplitCommand Split document at specified points

9.5 Desktop Services

Service Purpose
AuthService Manage authentication tokens via Tauri secure storage
ConnectionModeService Switch between local, remote, and hybrid backend connections
OperationRouter Route operations to local backend or remote server based on connection mode
TauriBackendService Lifecycle management for the embedded backend process
SaasBillingService SaaS billing integration for desktop users
BackendHealthMonitor Periodic health checks on the backend, auto-restart on failure

9.6 AI Engine Agents

Agent Input Output Use Case
OrchestratorAgent Natural language request Tool selection + parameters "Convert this to Word and compress it"
PdfEditAgent Edit instructions + PDF Modified PDF "Add a header to every page"
PdfQuestionAgent Question + PDF Natural language answer "What is the total on page 3?"
UserSpecAgent Requirements description Specification document Draft/revise functional specs
ExecutionPlanningAgent Multi-step request Ordered operation plan Plan complex multi-tool workflows
MathAuditorAgent Financial PDF Audit report Verify ledger entries, check calculations

Supporting classes:

  • AppRuntime: Application lifecycle and configuration
  • PostHogSpanProcessor: Telemetry span processing for AI agent traces

10. Supported Operations

The platform supports 38 distinct operation types (defined in engine/tool_models.py):

Operation Description
addAttachments Embed files into a PDF
addPassword Password-protect a PDF
adjustContrast Adjust page contrast/brightness
autoRename AI-based file renaming from content
automate Run automation pipelines
bookletImposition Arrange pages for booklet printing
certSign Apply certificate-based digital signature
changeMetadata Edit PDF metadata (title, author, etc.)
changePermissions Set PDF permission flags
compress Reduce PDF file size
convert Convert between file formats
crop Crop page margins
editTableOfContents Modify PDF bookmarks/TOC
extractImages Extract embedded images
extractPages Extract specific page ranges
flatten Flatten form fields and annotations
merge Combine multiple PDFs
ocr Optical character recognition
overlayPdfs Overlay one PDF on another
pageLayout Multi-page layout (N-up)
pdfToSinglePage Combine all pages into one continuous page
redact Permanently remove sensitive content
removeAnnotations Strip all annotations
removeBlanks Detect and remove blank pages
removeCertSign Remove digital signatures
removeImage Remove images from PDF
removePages Delete specific pages
removePassword Decrypt a password-protected PDF
reorganizePages Reorder pages
repair Repair corrupted PDFs
replaceColor Replace colors in PDF content
rotate Rotate pages
sanitize Remove hidden data, scripts, metadata
scalePages Resize pages
scannerImageSplit Split scanned image pages
sign Add visual signature
split Split into multiple PDFs
unlockPDFForms Make locked form fields editable
watermark Add text/image watermark

11. Testing

11.1 Test Infrastructure

Test Type Location Framework Command
Backend unit tests app/core/src/test/, app/common/src/test/, app/proprietary/src/test/ JUnit 5 ./gradlew test
Frontend unit tests frontend/src/ Vitest cd frontend && npm test
Frontend E2E tests frontend/ Playwright cd frontend && npm run test:e2e
BDD tests testing/cucumber/ Cucumber Via Gradle
AI engine tests engine/tests/ pytest cd engine && pytest
Docker CI/CD test_cicd.yml Docker Compose Compose-based integration
Test driver testing/testdriver/ — End-to-end test orchestration

11.2 Translation Validation

Stirling-PDF includes automated translation quality checks:

Validator Purpose
TOML validator Validates TOML translation file syntax
JSON structure validator Ensures translation JSON files have consistent structure
Placeholder validator Verifies {0}, {1}, etc. placeholders match across translations

11.3 CI/CD Test Configuration

The test_cicd.yml Docker Compose file sets up a test environment with API key authentication enabled, allowing automated integration testing against a running container.

Tip

Run the full test suite before submitting PRs: ./gradlew build test spotlessCheck for backend, and cd frontend && npm run test && npm run lint for frontend.


12. Troubleshooting

12.1 Container Fails to Start

Error: Container exits immediately or health check fails.

Cause: Insufficient memory for JVM startup, misconfigured SYSTEM_ROOTURIPATH, or port conflict.

Solution:

  1. Check logs: docker logs stirling-pdf
  2. Verify memory: ensure at least 512 MB available
  3. Check port availability: docker ps for conflicts on 8080
  4. If using SYSTEM_ROOTURIPATH, ensure it starts with / and has no trailing slash

Prevention: Always configure healthcheck.start_period to at least 60 seconds to allow JVM warm-up.

12.2 LibreOffice Conversion Failures

Error: file-to-pdf, pdf-to-word, or similar endpoints return 500 errors.

Cause: LibreOffice not installed (standard/ultra-lite image), UNO server not running, or session limit exceeded.

Solution:

  1. Verify image type: use fat image or install LibreOffice manually
  2. Check UNO server: docker exec stirling-pdf ps aux | grep soffice
  3. If remote UNO: verify shared /tmp/stirling-pdf volume and network connectivity
  4. Increase session limit: PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT=4

Prevention: Use the fat Docker image for deployments requiring document conversion.

12.3 OCR Returns Empty Text

Error: ocr-pdf endpoint produces a PDF with no recognized text.

Cause: Missing Tesseract language data for the document's language.

Solution:

  1. Install required language: TESSERACT_LANGS=eng,fra,deu (rebuild container)
  2. Or mount traineddata files: -v ./tessdata:/usr/share/tessdata
  3. Verify language availability inside container: ls /usr/share/tessdata/

Prevention: Pre-install all expected languages via TESSERACT_LANGS.

12.4 Large File Upload Fails

Error: 413 Request Entity Too Large or upload timeout.

Cause: SYSTEM_MAXFILESIZE too low, or reverse proxy body size limit.

Solution:

  1. Increase SYSTEM_MAXFILESIZE (in MB)
  2. Match reverse proxy limit: client_max_body_size 500M; in Nginx
  3. Increase proxy timeout for large files

Prevention: Set consistent limits across Stirling-PDF config and reverse proxy.

12.5 Endpoints Show as Disabled

Error: UI shows certain operations as unavailable.

Cause: Missing external tool dependency, or group disabled via configuration.

Solution:

  1. Check endpoint status via API: GET /api/v1/info/status
  2. Review disable reason (CONFIG vs DEPENDENCY)
  3. For DEPENDENCY: install the required tool or switch to fat image
  4. For CONFIG: review settings.yml and ENDPOINTS_GROUPS_TO_REMOVE

Prevention: Use the fat Docker image to ensure all dependencies are present.

12.6 Split Frontend Cannot Reach Backend

Error: Frontend shows connection errors or blank pages.

Cause: VITE_API_BASE_URL not set or set to unreachable address.

Solution:

  1. Verify VITE_API_BASE_URL points to the backend's actual URL
  2. Ensure backend is running and healthy
  3. Check network connectivity between frontend and backend containers
  4. Verify CORS configuration if frontend and backend are on different domains

Prevention: Use Docker Compose networking (service names) for container-to-container communication.

Caution

When running in split mode, the backend URL must be accessible from both the frontend container (for SSR/proxying) and the end user's browser (for client-side API calls). Ensure the URL is publicly reachable or configure appropriate proxy rules.

12.7 Database Import Constraint Error

Error: Database import fails with constraint violation (relates to GitHub issue #4405).

Cause: Schema migration conflict or duplicate key in imported data.

Solution:

  1. Back up existing database before import
  2. Verify the import file matches the current schema version
  3. If upgrading from an older version, let the application run its migrations first, then import

Prevention: Always export/import databases between matching application versions.

12.8 Windows SmartScreen Blocks Desktop Installer

Error: Windows SmartScreen prevents the desktop installer from running (GitHub issue #5600).

Cause: The executable is not yet widely distributed enough to build SmartScreen reputation, or code signing certificate is not recognized.

Solution:

  1. Click "More info" then "Run anyway" in the SmartScreen dialog
  2. Alternatively, right-click the installer, go to Properties, and check "Unblock"
  3. For enterprise deployment, add the installer hash to your organization's allow list via Group Policy

Prevention: Enterprise administrators should pre-approve the installer via WDAC or AppLocker policies.


13. API Reference

13.1 Authentication

API requests can be authenticated via:

# Per-user API key
curl -H "X-API-KEY: your-api-key" http://localhost:8080/api/v1/info/status

# Global API key (if SECURITY_CUSTOMGLOBALAPIKEY is set)
curl -H "X-API-KEY: global-key" http://localhost:8080/api/v1/info/status

13.2 Core Endpoints

The API exposes endpoints matching the 38 operation types listed in Section 10. Each operation accepts multipart form data with the PDF file and operation-specific parameters.

General pattern:

# Example: Merge PDFs
curl -X POST http://localhost:8080/api/v1/general/merge-pdfs \
  -H "X-API-KEY: your-key" \
  -F "fileInput=@file1.pdf" \
  -F "fileInput=@file2.pdf"

# Example: Compress PDF
curl -X POST http://localhost:8080/api/v1/general/compress-pdf \
  -H "X-API-KEY: your-key" \
  -F "fileInput=@document.pdf" \
  -F "optimizeLevel=3"

# Example: OCR
curl -X POST http://localhost:8080/api/v1/misc/ocr-pdf \
  -H "X-API-KEY: your-key" \
  -F "fileInput=@scanned.pdf" \
  -F "languages=eng"

13.3 Info Endpoints

# Health/status check
GET /api/v1/info/status

# Application information
GET /api/v1/info

13.4 AI Engine Endpoints

When the AI engine is running:

# Orchestrate a natural language request
POST /orchestrate

# Ask questions about a PDF
POST /pdf_questions

# AI-guided PDF editing
POST /pdf_edit

# Draft a specification
POST /draft

# Revise a specification
POST /revise

# Get next action recommendation
POST /next-action

# Examine a document
POST /examine

# Deliberate on a complex request
POST /deliberate

# Health check
GET /health

14. Integration Points

14.1 PostHog Analytics

Both the frontend (SaaS module) and the AI engine support PostHog telemetry:

  • AI Engine: Set STIRLING_POSTHOG_ENABLED=true, STIRLING_POSTHOG_API_KEY, and STIRLING_POSTHOG_HOST
  • Frontend SaaS: PostHog is integrated in the SaaS deployment module for user behavior analytics

14.2 Google Drive

The GoogleDrivePickerService in the frontend core enables importing files directly from Google Drive into Stirling-PDF operations.

14.3 Stripe Billing

The proprietary frontend module includes Stripe checkout integration for SaaS billing scenarios.

14.4 Windows Shell Integration

The Windows thumbnail handler DLL (stirling_thumbnail_handler.dll) registers as a COM IThumbnailProvider for the .pdf file extension, providing native PDF thumbnails in Windows Explorer when the desktop app is installed.

14.5 Enterprise Provisioner

The Tauri provisioner tool allows enterprise IT to preconfigure desktop installations:

  • Lock the server URL to a specific Stirling-PDF instance
  • Prevent users from switching connection modes
  • Deploy via standard MSI/MSIX enterprise deployment tools

15. Known Issues

Issue Status Description
#1612 Open Split PDF operation removes input fields from the resulting documents
#4405 Open Database import fails with constraint violation errors
#5951 Open Docker image crash under certain conditions
#6120 Open False positive virus detection on v2.9.2 binaries
#5600 Open Windows SmartScreen blocks the desktop installer
#6123 Open French translation issues in certain UI strings

Warning

Issue #6120 (false positive virus detection) affects v2.9.2 specifically. If your security software flags the Docker image or desktop binary, verify the checksum against the official release and add an exception if it matches.


16. Quick Reference

16.1 Minimal Docker Run

docker run -d -p 8080:8080 stirlingtools/stirling-pdf:latest

16.2 Production Docker Compose

version: "3.8"
services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:latest-fat
    ports:
      - "8080:8080"
    volumes:
      - ./configs:/configs
      - ./logs:/logs
      - ./tessdata:/usr/share/tessdata
      - ./customFiles:/customFiles
      - ./pipeline:/pipeline
    environment:
      - DOCKER_ENABLE_SECURITY=true
      - SECURITY_ENABLELOGIN=true
      - FAT_DOCKER=true
      - SYSTEM_MAXFILESIZE=200
      - SYSTEM_DEFAULTLOCALE=en-US
      - TESSERACT_LANGS=eng,fra,deu,spa
      - METRICS_ENABLED=true
      - STIRLING_JVM_PROFILE=balanced
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/info/status"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

16.3 Key Paths Inside Container

Path Purpose
/configs/settings.yml Primary configuration
/logs/ Application logs
/usr/share/tessdata/ OCR language data
/customFiles/ UI customization
/pipeline/ Automation pipelines
/tmp/stirling-pdf/ Temporary files (shared for remote UNO)

16.4 Contributing Checklist

./gradlew spotlessApply   # Format Java code
./gradlew test            # Run backend tests
cd frontend && npm test   # Run frontend tests
./gradlew build           # Full build verification