How to Use Stirling-PDF: The Beginner's Guide (First Docker Run, the Lock-It-Down Rule, OCR Languages, and the API That Comes Free)
CodexFuse Team · 2026-10-31T09:44:32.209Z · 18 min read min read
Stirling-PDF is a free, open-source, self-hosted PDF toolbox. This beginner guide covers the first Docker run, securing the default login, OCR languages, nginx HTTPS, and the free REST API.
How to Use Stirling-PDF: The Beginner's Guide (First Docker Run, the Lock-It-Down Rule, OCR Languages, and the API That Comes Free)
Learning how to use Stirling-PDF is the moment your PDF workflow stops depending on websites you do not trust. Stirling-PDF is a free, open-source, self-hosted PDF toolbox: more than 50 tools — merge, split, compress, sign, redact, convert, and OCR — running in one Docker container on your own server, so contracts, tax forms, and ID scans never leave your machine. This Stirling-PDF tutorial runs the complete beginner arc in one guide: choosing the right image, the first Docker Compose run, changing the default admin login before anyone else finds it, the lock-it-down rule for internet exposure, adding OCR languages beyond the bundled five, putting it behind nginx with HTTPS, and calling the free REST API. If you are new to Docker, skim the Docker beginner guide first — every Stirling-PDF install in this guide rides on it.
What is the fastest way to start using Stirling-PDF?
The fastest beginner path is: pick the standard image, start it with Docker Compose pinned to a version tag, bind the port to 127.0.0.1, set your own admin credentials before the first start, merge a test PDF, and lock the login down before any public exposure. In plain order, the steps are:
- Pick the standard image
docker.stirlingpdf.com/stirlingtools/stirling-pdf:3.2.2— it includes OCR, Office conversions, and login. - Create a folder, a
.envwith your own admin username and password, and acompose.yamlthat publishes port 8080 on127.0.0.1only, withmem_limit: 4g. - Run
docker compose pull && docker compose up -d, then confirm with the no-login status endpointcurl -s http://127.0.0.1:8080/api/v1/info/status. - Reach the UI through an SSH tunnel (
ssh -L 8080:127.0.0.1:8080 you@your-server) and log in with your own credentials — never the printed default. - Run your first real job: merge two PDFs, or run OCR on one scanned page.
- If a language is missing from the OCR list, add its
.traineddatafile to the tessdata volume and restart. - Put it behind nginx or a reverse proxy with
client_max_body_size 2000Mbefore it touches the public internet.
What exactly is Stirling-PDF?
Stirling-PDF is a locally hosted web application that gives you a full suite of PDF manipulation tools through a browser tab. Think of it as your private, offline Swiss Army knife for PDFs: instead of uploading a document to a random website, you open localhost:8080 and process the file on hardware you control. The project is developed openly on GitHub under the Stirling-Tools organization, and as of October 2026 it carries roughly 95,000 stars — the image has been pulled more than 16 million times from Docker Hub under the current stirlingtools/stirling-pdf name, with another 22 million pulls under the older frooodle/s-pdf name that still receives releases.
The toolbox groups its 50-plus tools into categories like Convert, Security, and Page Operations. Files are processed in the container's memory and removed once you download the result, so nothing accumulates on the server from one-off jobs. The repository is MIT licensed, with some folders (proprietary and SaaS code) under their own licenses. If you want the bigger picture of how much the world leans on this format, the roundup of PDF statistics for 2026 shows why a private toolkit is worth running.
How do I install Stirling-PDF with Docker Compose?
Docker Compose is the recommended install path, and the official compose file needs three beginner fixes: pin the version tag, publish the port on 127.0.0.1 only, and create your first admin account from a .env file. The docs use latest in their examples, but latest moves with every release — Stirling-PDF ships fast (3.0.0 on September 24, 3.1.0 on October 5, 3.2.0 on October 15, and 3.2.2 on October 24, 2026), so pinning a tag means updates happen when you choose, not when you pull.
Create the folder and the credentials first. The umask 077 step makes the .env readable only by you — the password inside unlocks an app that will hold your documents:
mkdir -p ~/stirling-pdf/stirling-data/tessdata && cd ~/stirling-pdf umask 077 cat > .env <<EOF SECURITY_INITIALLOGIN_USERNAME=pdfadmin SECURITY_INITIALLOGIN_PASSWORD=REPLACE-WITH-A-STRONG-PASSWORD EOF umask 022
Creating the tessdata folder in advance matters: if you let Docker create it, the folder belongs to root, and you will need sudo to copy language files in later. The other data folders end up owned by UID 1000, the user the container runs as. Then save this as compose.yaml:
services:
stirling-pdf:
image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:3.2.2
container_name: stirling-pdf
ports:
- "127.0.0.1:8080:8080"
environment:
SECURITY_INITIALLOGIN_USERNAME: ${SECURITY_INITIALLOGIN_USERNAME}
SECURITY_INITIALLOGIN_PASSWORD: ${SECURITY_INITIALLOGIN_PASSWORD}
volumes:
- ./stirling-data/configs:/configs
- ./stirling-data/logs:/logs
- ./stirling-data/customFiles:/customFiles
- ./stirling-data/pipeline:/pipeline
- ./stirling-data/storage:/storage
- ./stirling-data/tessdata:/usr/share/tessdata
mem_limit: 4g
restart: unless-stopped
Start it and check the built-in health endpoint, which needs no login and makes a perfect uptime-monitor target:
docker compose pull docker compose up -d curl -s http://127.0.0.1:8080/api/v1/info/status
About twenty seconds after startup the endpoint answers {"version":"3.2.2","status":"UP"}. Keep the mem_limit: the image sizes the Java heap from it, and without a limit the heap is sized from the host's RAM, which is why people see Stirling-PDF eat memory while idle. One important note for older guides: the image moved from frooodle/s-pdf to stirlingtools/stirling-pdf (and in V2 to the docker.stirlingpdf.com registry). Any tutorial still citing the old image name is out of date.
Which Stirling-PDF image should I choose: standard, fat, or ultra-lite?
Beginners should run the standard image. Stirling-PDF ships three variants, and the difference is login, OCR, and memory — choosing wrong means either no login at all or no OCR when you need it:
| Tag | Login | What is included | Suggested memory |
|---|---|---|---|
| 3.2.2 (standard) | Yes | OCR plus Office, HTML, and ebook conversion | 4 GB |
| 3.2.2-fat | Yes | The same plus a bundled AI engine, off until you turn it on | 6 GB |
| 3.2.2-ultra-lite | No | Core PDF tools only — no OCR, no conversions | 2 GB |
The size gap is real: the compressed download was 1.17 GB for the standard 3.2.0 image against 394 MB for ultra-lite, and 3.58 GB against 1.04 GB on disk. Ultra-lite idled at 357 MiB of RAM while the standard image used 795 MiB to 1.08 GiB — but ultra-lite has no login at all, API calls work without credentials, and the OCR endpoint answers with a 403. Only run ultra-lite on a network you fully trust. All three tags exist on docker.stirlingpdf.com, Docker Hub, and ghcr.io.
How do I change the default Stirling-PDF login?
Do it before the first start by setting the two environment variables above, or change it immediately after the first login — never leave the default in place. A fresh standard install creates the account admin with the password stirling, and the login page prints both in a "Default Login Credentials" box that every visitor can read. The first login forces a password change (minimum 8 characters) and then removes the credentials box. An account locks for 120 minutes after 5 failed attempts.
The .env approach from the compose file skips all of that: with SECURITY_INITIALLOGIN_USERNAME=pdfadmin set before the first start, no credentials box ever appears, and admin / stirling get a 401. Both variables are ignored once the user database has users, so changing them later does nothing — change the password inside the app instead. If you disable login entirely with SECURITY_ENABLELOGIN=false, know what that means: anyone who can reach the server can use every tool. With login on, the API is protected too — an unauthenticated request to /api/v1/misc/ocr-pdf gets a 401, while the endpoint descriptions at /v1/api-docs stay public.
Why must I lock Stirling-PDF down before exposing it?
Because the upstream compose file publishes port 8080 on every interface, and Docker's published ports bypass host firewall rules like ufw — so a fresh install with the default login is one port scan away from a stranger reading your documents. This is the lock-it-down rule: bind to 127.0.0.1 (done in the compose file above), reach the UI through an SSH tunnel or a reverse proxy with HTTPS, and set DOCKER_ENABLE_SECURITY=true and SECURITY_ENABLELOGIN before the instance is ever reachable from the internet.
For anything facing the web, what is VPS hosting is worth understanding first — Stirling-PDF belongs on a server you control, behind a real domain and TLS, with only 22, 80, and 443 open. The install docs also ask you to set SYSTEM_FRONTENDURL to your public address, because invite emails and share links are built from it. And keep your own admin password in a password manager: the .env file holds the keys to every document the instance will ever see.
How do I run my first merge and split in Stirling-PDF?
Open the UI, go to the Page Operations section, and run one merge and one split on files you can afford to lose — the tools are click-driven, so the first useful thing to learn is where they live. Pick two small PDFs, use the merge tool, and download the result. Then split a multi-page PDF into single pages. If you want the hosted one-off version of the same operations first, the guides to merge PDF files and split a PDF teach the underlying ideas; Stirling-PDF gives you the same operations privately, with no upload limits and no watermarks.
Two tools worth trying in the same first session: Auto Redact, which blacks out every occurrence of a word or phrase you type (handy for contracts), and the password-protection tool. Note its gap honestly: when you set an owner password to restrict what can be done with a document, some restrictions are enforced by the reader software, not by cryptography — so treat it as a deterrent, not a vault.
How do I OCR a scanned PDF in Stirling-PDF?
Upload the scan, open the OCR tool, pick your languages, and run it — the standard image does this with OCRmyPDF and Tesseract built in. The standard image ships Tesseract data for Simplified Chinese, English, French, German, and Portuguese (chi_sim, deu, eng, fra, osd, por). The web UI only lists installed languages, so if your language is missing, the OCR tool will not offer it.
A tested example: a scanned English invoice OCR'd through the API in about 2 seconds with the invoice number, date, and amounts coming back correct. A scanned Spanish letter asked for before Spanish was installed returned an HTTP 400 error ("none of the selected languages are valid"); running it with English instead stripped every accent — "señora Núñez" came back as "sefiora Niifiez". After Spanish was added (see the next section), the accents and the ñ came out right, with a few remaining errors on the noisiest words. OCR on a rough scan is never perfect in any language — check important documents.
How do I add more OCR languages to Stirling-PDF?
Download the language's .traineddata file, drop it in the folder mounted at /usr/share/tessdata, and restart the container. The volume must be mounted at exactly /usr/share/tessdata inside the container — in a GitHub issue where a user had mounted language files at /data/tessdata, the maintainer answered that every doc shows /usr/share/tessdata, and nothing else works.
cd ~/stirling-pdf curl -fL -o stirling-data/tessdata/spa.traineddata \ https://github.com/tesseract-ocr/tessdata/raw/main/spa.traineddata docker compose restart docker exec stirling-pdf tesseract --list-langs
Get the .traineddata from the tesseract-ocr/tessdata repository (larger, more accurate) or tessdata_fast (smaller, faster). At startup the log confirms with "Found user-mounted tessdata, copying to the Tesseract folder", and the language joins the list. Two rules: keep eng.traineddata in place because English is always needed, and use the volume — the in-app download under Settings, then Server, then Advanced puts files inside the container, so they disappear the next time you recreate it.
How do I put Stirling-PDF behind nginx with HTTPS?
Point a reverse proxy at 127.0.0.1:8080 and set client_max_body_size 2000M — without it, uploads bigger than 1 MB die with a 413. Nginx accepts 1 MB request bodies by default, and PDFs are almost always bigger: a 2.6 MB four-page scan sent through a plain proxy_pass failed with "413 Request Entity Too Large" before this setting was added. The production checklist in the docs fixes it:
server {
# listen 443 ssl, server_name and certificates as usual
client_max_body_size 2000M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_buffering off;
proxy_read_timeout 1800s;
proxy_send_timeout 1800s;
}
}
The same request then returned 200 in 2.2 seconds with all four pages OCR'd. 2000 MB matches Stirling-PDF's own default upload limit, and the long timeouts plus proxy_buffering off exist for slow jobs like big OCR runs. Nginx Proxy Manager already sets a 2000 MB limit in its main config, so this mostly bites hand-written nginx setups. If you prefer a dashboard to a config file, the same compose file works as a Docker Compose resource in Coolify, and Traefik-based setups are covered in the community guides.
What can the Stirling-PDF REST API do?
Almost every tool in the UI is also an API endpoint, and with login on, the API needs the same credentials. That is the short version — and it is what makes Stirling-PDF scriptable: conversions, OCR, compression, and splitting can all run from a cron job or a pipeline without a browser.
Start with the two freebies: the status endpoint needs no login and returns {"version":"3.2.2","status":"UP"}, and the endpoint descriptions at /v1/api-docs (plus the Swagger page) answer without login too — they only describe the endpoints. Everything that touches a file needs credentials. The pattern for a real call:
curl -s http://127.0.0.1:8080/api/v1/info/status
# {"version":"3.2.2","status":"UP"}
curl -s -u pdfadmin:YOUR-PASSWORD \
-F "[email protected]" \
-F "ocrType=force-ocr" -F "languages=eng" \
http://127.0.0.1:8080/api/v1/misc/ocr-pdf -o scan-ocr.pdf
Without credentials, a POST to the OCR endpoint returns 401. On the ultra-lite image there is no login at all, so its API answers without credentials — another reason ultra-lite belongs only on trusted networks. If you want every scan OCR'd and filed automatically instead of one-off jobs, note the honest split: Paperless-ngx uses the same OCRmyPDF and Tesseract tools on each document it imports, while Stirling-PDF fits one-off jobs better.
How do I update and back up Stirling-PDF?
Back up first, then change the tag and recreate the container — updates are a three-command job because the app is stateless. File processing keeps nothing: only configuration and OCR language data live in volumes, so the backup is small:
cd ~/stirling-pdf tar czf stirling-backup-$(date +%F).tgz stirling-data/configs stirling-data/storage sed -i 's/stirling-pdf:3.2.1/stirling-pdf:3.2.2/' compose.yaml docker compose pull && docker compose up -d curl -s http://127.0.0.1:8080/api/v1/info/status
The configs folder holds settings, keys, and the built-in database — which also writes a nightly backup to configs/backup/db/ — and storage holds files users saved on the server. On first start the app creates a credential-encryption.key in /configs and logs a warning to back it up, because losing it makes stored integration secrets unrecoverable. Read the release notes before each bump: releases come fast, and coming from V1 you should read the upgrade guide the install docs link to first. A tested upgrade from 3.1.0 to 3.2.0 answered the new version about 22 seconds after recreate, and the admin from the first start could still log in.
Stirling-PDF vs Adobe Acrobat: which should I use?
Use Stirling-PDF when your documents are private and your jobs are batch-shaped; use Acrobat when you need the polished desktop editor. This Stirling-PDF vs Adobe comparison is the honest version — they overlap on features but not on philosophy:
| Question | Stirling-PDF (self-hosted) | Adobe Acrobat |
|---|---|---|
| Where do files go? | Processed in your container's memory, removed after download | Uploaded to Adobe's cloud (or a third-party site) for online tools |
| Cost | Free to self-host — all PDF tools, REST API, and OAuth2 single sign-on for up to 5 users; paid Team and Enterprise plans add users and features like an external database | Paid subscription |
| Offline use | Yes — runs on your LAN with no internet at all | Desktop app works offline; online tools need the cloud |
| Batch and API | Free REST API for every tool; scriptable from cron and pipelines | API access is a separate paid tier |
| OCR languages | You manage Tesseract language packs yourself | Managed for you |
| Effort | You install, secure, and update a Docker container | None — it is a service |
The deciding question is trust, not price: if the PDF holds contracts, medical forms, or ID scans, a self-hosted Stirling-PDF means those files never cross a boundary you do not control. If the PDF is a public brochure and you just want it compressed in ten seconds, the hosted per-operation guides are faster. The per-operation how-tos behind the hosted angle — split, merge, convert, extract images, delete pages — already live in this site's PDF-tools cluster; this guide fills the missing lane, running the whole suite yourself.
What mistakes do beginners make with Stirling-PDF?
Almost every broken Stirling-PDF install comes from the same short list. The defaults are generous and trusting; production is neither:
| Mistake | What happens | The fix |
|---|---|---|
| Publishing 8080 on all interfaces with the default login | Anyone on the internet can open your instance and read the printed admin password | Bind to 127.0.0.1, use SSH tunnel or HTTPS proxy, set your own credentials before first start |
Using the latest tag | An update lands when you pull, not when you are ready — releases ship every week or two | Pin a version tag like 3.2.2; bump deliberately after reading the release notes |
No mem_limit | The Java heap is sized from host RAM; idle memory looks alarming | Set mem_limit: 4g in compose |
| OCR language files in the wrong path | The language never appears; the API returns "none of the selected languages are valid" | Mount at exactly /usr/share/tessdata, restart, verify with tesseract --list-langs |
| Hand-written nginx without the body-size setting | Uploads over 1 MB fail with 413 | client_max_body_size 2000M in the server block |
| Backing up only the database | Stored integration secrets are unrecoverable without it | Include /configs — especially credential-encryption.key — in every backup |
Sources
Every fact in this guide was fetched on October 31, 2026, from these sources:
- GitHub API, Stirling-Tools/Stirling-PDF — latest release v3.2.2 published October 24, 2026; ~95,437 stars.
- DeployLark on dev.to, "Stirling-PDF Docker Setup: Login, OCR Languages and Updates" (published October 18, 2026) — full Debian 13 test on 3.2.0: the compose file with pinned tag, 127.0.0.1 binding, and
mem_limit: 4g; the admin/stirling default printed on the login page; forced password change and 120-minute lockout; the standard/fat/ultra-lite comparison (1.17 GB vs 394 MB compressed, 3.58 GB vs 1.04 GB on disk, 795 MiB–1.08 GiB vs 357 MiB RAM); built-in OCR languages; the Spanishspa.traineddataaddition; the/usr/share/tessdatapath rule; nginx 1 MB default and the 413 on a 2.6 MB upload;client_max_body_size 2000M;SYSTEM_FRONTENDURL; backup tarball of configs and storage; the three-command update; release dates 3.0.0 (September 24), 3.1.0 (October 5), 3.2.0 (October 15), 2026; ~94,300 stars and ~16.3M Docker Hub pulls as of October 17, 2026; tool versions OpenJDK 25.0.4, OCRmyPDF 17.13.0, Tesseract 5.3.4, LibreOffice 26.2.6.3, Ghostscript 10.08.0, qpdf 12.4.2, calibre 9.15.0. - Serverkueche on dev.to, "Stirling-PDF: The PDF Toolbox on Your Own Server" (October 2026) — v2.14.2 Traefik arc, login as first line of defense, 20–30 second health check, stateless processing with configs-plus-OCR-data backup.
- MakeUseOf, "55+ PDF tools fit inside this Docker container" (August 30, 2026) — 50-plus features in one container, files processed in memory and deleted after download, UI categories, paid team tier with SSO and unlimited users.
- mariushosting.com, "How to Install Stirling-PDF on Your Asustor NAS" (October 2026) — v3.2.2 on
docker.stirlingpdf.com/stirlingtools/stirling-pdf, port mapping, and the config/customfiles/data/logs/pipeline folder layout. - bitdoze.com, "Stirling-PDF Self-Host Manipulation" (2026) — V2 Docker deploy with Traefik, DNS, and HTTPS; UI_APPNAME and UI_HOMEDESCRIPTION envs removed in V2.
- elest.io, "Self-Host Stirling-PDF: 50 Private PDF Tools on Your Server" (2026) — the lock-it-down lesson: DOCKER_ENABLE_SECURITY and SECURITY_ENABLELOGIN before exposing.
- mustafaerbay.com.tr, Stirling-PDF install walkthrough (2026) — nginx reverse-proxy with basic-ops walkthrough of merge, split, compress, and OCR.
- typevar.dev, "Stirling-PDF: Your Privacy-First PDF Toolkit for Engineers" — self-hosted overview and the older
stirling/pdfimage reference.
Frequently asked questions
What is the default username and password for Stirling-PDF?
admin and stirling. A fresh standard image creates that account and shows it on the login page until you change the password, which the first login forces. To skip the default account entirely, set SECURITY_INITIALLOGIN_USERNAME and SECURITY_INITIALLOGIN_PASSWORD before the first start — they only apply while the user database is empty.
Can I run Stirling-PDF without a login?
Yes. Set SECURITY_ENABLELOGIN=false, or use the ultra-lite image, which has no login at all. Then anyone who can reach the port can use every tool and the API, so keep it on 127.0.0.1 or a private network. For anything internet-facing, login plus HTTPS is mandatory.
Is Stirling-PDF free to self-host?
Yes. The repository is MIT licensed, and a self-hosted server runs on the Free plan with all PDF tools, the REST API, and OAuth2 single sign-on for up to 5 users. Team and Enterprise plans add more users and features like an external database.
Why does Stirling-PDF use so much RAM?
Java sizes its heap from the memory it sees. Set mem_limit in compose or --memory with docker run: with a 4 GB limit the standard container idles between 795 MiB and 1.08 GiB. If that is too much and you do not need OCR or conversions, ultra-lite idles around 357 MiB.
Why do large uploads fail behind my reverse proxy?
The proxy is rejecting the upload. Nginx allows 1 MB request bodies by default and returns 413 for anything bigger. Set client_max_body_size 2000M in the server block and reload nginx — Nginx Proxy Manager already allows 2000 MB, so this mostly bites hand-written configs.