A PDF Tool That Stays on Your Server
Stirling PDF is an open-source, self-hosted web application that handles nearly every PDF operation you would otherwise trust to an online service – merging, splitting, compressing, converting, watermarking, rotating, and more. Unlike browser-based tools that upload your documents to someone else’s infrastructure, Stirling PDF runs entirely within your own environment. Your files never leave the machine you control.
The project is Docker-friendly, actively maintained, and ships with a clean web interface that requires no technical knowledge to use once it is running. Setting it up takes about fifteen minutes, and the result is a permanent, private PDF toolkit accessible from any browser on your network. This guide walks through the full setup using Docker Compose on a Linux host, which is the most common and straightforward deployment path.

What You Need Before Starting
The requirements are minimal. You need a Linux server or home lab machine – a Raspberry Pi 4, an old desktop, or a VPS all work – with Docker and Docker Compose installed. The host should have at least 1 GB of RAM available for Stirling PDF, though 2 GB gives it comfortable headroom when processing large files. A stable local IP address or a domain pointed at the machine is useful if you want to access the tool from outside your home network, but for local-only use the default setup is enough.
Make sure Docker is running and that your user account has permission to execute Docker commands without sudo, or that you are comfortable running commands with elevated privileges. You can verify Docker is working by running docker run hello-world in a terminal. If that completes without error, your environment is ready. Confirm Docker Compose is available with docker compose version – you want version 2.x or later.
Creating the Docker Compose File
Create a directory for the project and navigate into it. A clean name like stirling-pdf in your home directory keeps things organized. Inside that directory, create a file named docker-compose.yml using your preferred text editor.
Paste the following configuration into that file:
version: ‘3.3’
services:
stirling-pdf:
image: frooodle/s-pdf:latest
ports:
– ‘8080:8080’
volumes:
– ./trainingData:/usr/share/tesseract-ocr/5/tessdata
– ./extraConfigs:/configs
– ./customFiles:/customFiles
environment:
– DOCKER_ENABLE_SECURITY=false
– INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false
– LANGS=en_GB
restart: unless-stopped
The port mapping exposes the application at port 8080 on the host. If something else on your server is already using that port, change the left number – for example, 8090:8080 would work equally well. The three volume mounts create persistent local directories for OCR language data, application configuration, and any custom files. The environment variable INSTALL_BOOK_AND_ADVANCED_HTML_OPS is set to false by default because enabling it triggers additional package installations inside the container and extends startup time significantly; you can set it to true later if you need Calibre-based conversions. The LANGS variable controls which OCR language pack loads at startup – swap en_GB for your preferred language code if needed.
Save the file once you have reviewed the configuration. The directory structure that Docker Compose expects does not need to exist beforehand – Docker will create the local volumes on first run. The restart: unless-stopped directive ensures Stirling PDF comes back automatically if the host reboots or the container crashes.

Starting the Container
From inside the stirling-pdf directory, run docker compose up -d. Docker will pull the latest image from the repository and start the container in detached mode. The first pull takes a minute or two depending on your connection speed. Once it completes, you can check that the container is running with docker compose ps, which should show the service as Up.
Open a browser and navigate to http://your-server-ip:8080. The Stirling PDF interface loads immediately – no account creation, no email confirmation. You see a grid of tools organized by category: organize, convert, security, edit, and others. Every tool on that page runs locally on your server the moment you interact with it.
Enabling OCR and Optional Features
Out of the box, Stirling PDF includes basic OCR support through Tesseract, but only for the language specified in the LANGS variable. If you need OCR in additional languages, you can copy Tesseract language data files – files with a .traineddata extension – directly into the trainingData directory that was created when the container first started. Tesseract language packs are widely available through your distribution’s package manager or the official Tesseract GitHub repository. Drop the file into the directory and restart the container with docker compose restart for the new language to become available in the OCR tool.
Authentication is disabled by default, which is appropriate for a home network where you trust all connected devices. If you plan to expose Stirling PDF to the internet – through a reverse proxy like Nginx Proxy Manager or Caddy, for example – you should enable the built-in security layer. Change the environment variable DOCKER_ENABLE_SECURITY=false to true in your Compose file, then run docker compose up -d again to apply the change. This activates a login system with user accounts managed through the application settings.

For teams or households where multiple people will use the tool, Stirling PDF supports basic user roles once security is enabled – an admin account for managing settings and standard accounts for everyday use. The admin panel is accessible through the settings icon in the top navigation. From there you can also configure custom application names, logo overrides, and default language settings, which is useful if you want to white-label the interface for a small office deployment. Configuration changes persist in the extraConfigs volume, so they survive container updates without any extra steps. To update Stirling PDF itself, run docker compose pull followed by docker compose up -d, and Docker replaces the running container with the latest image while keeping all your stored configuration intact.





