A PDF Tool That Stays on Your Server
Most PDF utilities come with a catch – you upload your files to someone else’s server, trust their privacy policy, and hope your documents don’t end up in a training dataset. Stirling PDF sidesteps that entirely. It’s an open-source, self-hosted web application that runs locally on your own machine or home server, giving you a full suite of PDF tools without any file ever leaving your network. Split, merge, rotate, compress, convert, watermark, OCR – it handles all of it through a clean browser interface.
The appeal goes beyond privacy. Stirling PDF packages roughly 50 operations into a single Docker container, which means there’s no subscription, no file size limit imposed by a third party, and no waiting in a processing queue with anonymous strangers. You deploy it once, and it’s available to every device on your network indefinitely. For anyone handling sensitive documents regularly – contracts, tax records, medical files – this is a meaningfully different setup than uploading PDFs to a web tool and hoping for the best.

What You Need Before Starting
Stirling PDF runs inside Docker, so the main prerequisite is having Docker and Docker Compose installed on your host machine. This could be a home server running Linux, a Raspberry Pi 4 or later, a NAS device that supports Docker, or even a Mac or Windows machine running Docker Desktop. The application is lightweight enough to run comfortably on a Raspberry Pi 4 with 4GB of RAM, though OCR processing will be noticeably slower on lower-powered hardware compared to a dedicated server or desktop machine.
You’ll also want to decide whether you’re exposing this service only on your local network or making it accessible remotely through a reverse proxy like Nginx Proxy Manager or Caddy. For most home users handling personal documents, local-only access is the simpler and safer choice. If you already have a reverse proxy running – perhaps alongside other self-hosted services on the same machine – adding Stirling PDF behind it takes only a few extra configuration lines.
Deploying the Container
Start by creating a directory to hold your Stirling PDF configuration and any training data you might use for OCR. On a Linux host, a path like /opt/stirling-pdf or /home/yourusername/stirling-pdf works well. Inside that directory, create a file named docker-compose.yml. This file tells Docker exactly how to run the container, which ports to expose, and where to store persistent data.
Paste the following into your compose 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
environment:
- DOCKER_ENABLE_SECURITY=false
- INSTALL_BOOK_AND_ADVANCED_HTML_COVER_CONS=false
restart: unless-stopped
The port mapping 8080:8080 means the application will be available at http://your-server-ip:8080 in your browser. If port 8080 is already in use by something else on your system, change the left side of the mapping to any unused port – for example 9090:8080. The volumes section maps two local directories into the container: one for Tesseract OCR language data, and one for any custom configuration files. Both directories will be created automatically when you first start the container, but you can also create them manually with mkdir trainingData extraConfigs before launching.

With your compose file saved, run docker compose up -d from inside the stirling-pdf directory. Docker will pull the image from Docker Hub, which is roughly 500MB to 1GB depending on the variant, and start the container in detached mode. Give it 30 to 60 seconds to initialize, then navigate to http://localhost:8080 or your server’s local IP address at that port. You should land on Stirling PDF’s home dashboard, which displays all available tools organized by category.
Configuring OCR and Language Support
Out of the box, Stirling PDF includes English OCR support through Tesseract, the open-source OCR engine. If you need to recognize text in other languages – French, German, Spanish, Japanese, Chinese, and many others – you’ll need to download the corresponding Tesseract language data files and place them in the trainingData directory you mapped in the compose file. Tesseract language files use the .traineddata extension and are freely available from the official Tesseract GitHub repository. Dropping a file like fra.traineddata into that folder and restarting the container is all it takes to add French OCR support.
The OCR feature in Stirling PDF works by processing a scanned PDF and returning a searchable PDF with the recognized text embedded as an invisible layer. This is particularly useful for scanned contracts, receipts, or archival documents where you want to search for specific text without manually retyping anything. Processing speed depends heavily on your hardware – a modern multi-core processor will handle a 20-page scanned document in under a minute, while a Raspberry Pi might take several minutes for the same job. Running the container on a machine with at least four CPU cores makes a noticeable difference for OCR-heavy workloads.
For users who want to lock down the interface with a login, Stirling PDF includes a basic security layer. Set DOCKER_ENABLE_SECURITY=true in the environment section of your compose file and add the environment variable SECURITY_ENABLELOGIN=true. On first launch with security enabled, the default credentials are admin and stirling – change these immediately through the settings panel. This matters most if you plan to expose the service outside your local network, where leaving default credentials in place would be a straightforward security problem.
If you’re running multiple self-hosted services on one machine – perhaps something like a Glances system monitoring dashboard alongside Stirling PDF – you’ll want to make sure the port assignments don’t conflict. Stirling PDF’s default port 8080 is commonly used by other applications, so checking your existing port mappings before deployment saves troubleshooting time later.

Updates to Stirling PDF come frequently, as the project is actively maintained and new tools get added on a rolling basis. Updating is a two-command process: docker compose pull to fetch the latest image, followed by docker compose up -d to recreate the container with the new version. Your configuration files and any custom OCR language data persist through updates because they live in the mapped volumes on your host, not inside the container itself. The one thing worth checking after a major update is whether the compose file format or environment variable names have changed – the project’s GitHub changelog covers any breaking configuration changes between versions, and skipping that check after a large version jump is how services end up broken and confusing to debug.





