Stirling PDF: Self-hosted, web-based PDF manipulation tool

https://github.com/Stirling-Tools/Stirling-PDF

Stirling-PDF

Docker Pulls Discord Docker Image Version (tag latest semver) GitHub Repo stars

Deploy to DO Name

This is a robust, locally hosted web-based PDF manipulation tool using Docker. It enables you to carry out various operations on PDF files, including splitting, merging, converting, reorganizing, adding images, rotating, compressing, and more. This locally hosted web application has evolved to encompass a comprehensive set of features, addressing all your PDF requirements.

Stirling PDF does not initiate any outbound calls for record-keeping or tracking purposes.

All files and PDFs exist either exclusively on the client side, reside in server memory only during task execution, or temporarily reside in a file solely for the execution of the task. Any file downloaded by the user will have been deleted from the server by that point.

stirling-home

Features

  • Dark mode support.
  • Custom download options
  • Parallel file processing and downloads
  • Custom 'Pipelines' to run multiple features in a queue
  • API for integration with external scripts
  • Optional Login and Authentication support (see here for documentation)
  • Database Backup and Import (see here for documentation)

PDF Features

Page Operations

  • View and modify PDFs - View multi page PDFs with custom viewing sorting and searching. Plus on page edit features like annotate, draw and adding text and images. (Using PDF.js with Joxit and Liberation.Liberation fonts)
  • Full interactive GUI for merging/splitting/rotating/moving PDFs and their pages.
  • Merge multiple PDFs together into a single resultant file.
  • Split PDFs into multiple files at specified page numbers or extract all pages as individual files.
  • Reorganize PDF pages into different orders.
  • Rotate PDFs in 90-degree increments.
  • Remove pages.
  • Multi-page layout (Format PDFs into a multi-paged page).
  • Scale page contents size by set %.
  • Adjust Contrast.
  • Crop PDF.
  • Auto Split PDF (With physically scanned page dividers).
  • Extract page(s).
  • Convert PDF to a single page.
  • Overlay PDFs ontop of each other

Conversion Operations

  • Convert PDFs to and from images.
  • Convert any common file to PDF (using LibreOffice).
  • Convert PDF to Word/Powerpoint/Others (using LibreOffice).
  • Convert HTML to PDF.
  • URL to PDF.
  • Markdown to PDF.

Security & Permissions

  • Add and remove passwords.
  • Change/set PDF Permissions.
  • Add watermark(s).
  • Certify/sign PDFs.
  • Sanitize PDFs.
  • Auto-redact text.

Other Operations

  • Add/Generate/Write signatures.
  • Repair PDFs.
  • Detect and remove blank pages.
  • Compare 2 PDFs and show differences in text.
  • Add images to PDFs.
  • Compress PDFs to decrease their filesize (Using OCRMyPDF).
  • Extract images from PDF.
  • Extract images from Scans.
  • Add page numbers.
  • Auto rename file by detecting PDF header text.
  • OCR on PDF (Using OCRMyPDF).
  • PDF/A conversion (Using OCRMyPDF).
  • Edit metadata.
  • Flatten PDFs.
  • Get all information on a PDF to view or export as JSON.
  • Show/Detect embedded Javascript

For a overview of the tasks and the technology each uses please view Endpoint-groups.md

Demo of the app is available here.

Technologies used

How to use

Locally

Please view https://github.com/Stirling-Tools/Stirling-PDF/blob/main/LocalRunGuide.md

Docker / Podman

https://hub.docker.com/r/frooodle/s-pdf

Stirling PDF has 3 different versions, a Full version and ultra-Lite version as well as a 'Fat' version. Depending on the types of features you use you may want a smaller image to save on space. To see what the different versions offer please look at our version mapping For people that don't mind about space optimization just use the latest tag. Docker Image Size (tag) Docker Image Size (tag) Docker Image Size (tag)

Please note in below examples you may need to change the volume paths as needed, current examples install them to the current working directory eg ./extraConfigs:/configs to /opt/stirlingpdf/extraConfigs:/configs

Docker Run

docker run -d \
  -p 8080:8080 \
  -v ./trainingData:/usr/share/tessdata \
  -v ./extraConfigs:/configs \
  -v ./logs:/logs \
  -e DOCKER_ENABLE_SECURITY=false \
  -e INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false \
  -e LANGS=en_GB \
  --name stirling-pdf \
  frooodle/s-pdf:latest
  Can also add these for customisation but are not required
  -v /location/of/customFiles:/customFiles \

Docker Compose

version: '3.3'
services:
  stirling-pdf:
    image: frooodle/s-pdf:latest
    ports:
      - '8080:8080'
    volumes:
      - ./trainingData:/usr/share/tessdata #Required for extra OCR languages
      - ./extraConfigs:/configs
#      - ./customFiles:/customFiles/
#      - ./logs:/logs/
    environment:
      - DOCKER_ENABLE_SECURITY=false
      - INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false
      - LANGS=en_GB

Note: Podman is CLI-compatible with Docker, so simply replace "docker" with "podman".

Enable OCR/Compression feature

Please view https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToUseOCR.md

Supported Languages

Stirling PDF currently supports 38!

Language Progress
Arabic (العربية) (ar_AR) 100%
Basque (Euskara) (eu_ES) 60%
Bulgarian (Български) (bg_BG) 92%
Catalan (Català) (ca_CA) 47%
Croatian (Hrvatski) (hr_HR) 92%
Czech (Česky) (cs_CZ) 88%
Danish (Dansk) (da_DK) 97%
Dutch (Nederlands) (nl_NL) 93%
English (English) (en_GB) 100%
English (US) (en_US) 100%
French (Français) (fr_FR) 91%
German (Deutsch) (de_DE) 99%
Greek (Ελληνικά) (el_GR) 80%
Hindi (हिंदी) (hi_IN) 76%
Hungarian (Magyar) (hu_HU) 73%
Indonesia (Bahasa Indonesia) (id_ID) 74%
Irish (Gaeilge) (ga_IE) 96%
Italian (Italiano) (it_IT) 99%
Japanese (日本語) (ja_JP) 90%
Korean (한국어) (ko_KR) 82%
Norwegian (Norsk) (no_NB) 95%
Polish (Polski) (pl_PL) 90%
Portuguese (Português) (pt_PT) 76%
Portuguese Brazilian (Português) (pt_BR) 99%
Romanian (Română) (ro_RO) 98%
Russian (Русский) (ru_RU) 82%
Serbian Latin alphabet (Srpski) (sr_LATN_RS) 76%
Simplified Chinese (简体中文) (zh_CN) 96%
Slovakian (Slovensky) (sk_SK) 90%
Spanish (Español) (es_ES) 99%
Swedish (Svenska) (sv_SE) 98%
Thai (ไทย) (th_TH) 97%
Traditional Chinese (繁體中文) (zh_TW) 96%
Turkish (Türkçe) (tr_TR) 96%
Ukrainian (Українська) (uk_UA) 87%
Vietnamese (Tiếng Việt) (vi_VN) 96%

Contributing (creating issues, translations, fixing bugs, etc.)

Please see our Contributing Guide!

Customisation

Stirling PDF allows easy customization of the app. Includes things like

  • Custom application name
  • Custom slogans, icons, HTML, images CSS etc (via file overrides)

There are two options for this, either using the generated settings file settings.yml This file is located in the /configs directory and follows standard YAML formatting

Environment variables are also supported and would override the settings file For example in the settings.yml you have

security:
  enableLogin: 'true'

To have this via an environment variable you would have SECURITY_ENABLELOGIN

The Current list of settings is

security:
  enableLogin: false # set to 'true' to enable login
  csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production)
  loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1
  loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts
  loginMethod: all # 'all' (Login Username/Password and OAuth2[must be enabled and configured]), 'normal'(only Login with Username/Password) or 'oauth2'(only Login with OAuth2)
  initialLogin:
    username: '' # Initial username for the first login
    password: '' # Initial password for the first login
  oauth2:
    enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work)
    client:
      keycloak:
        issuer: '' # URL of the Keycloak realm's OpenID Connect Discovery endpoint
        clientId: '' # Client ID for Keycloak OAuth2
        clientSecret: '' # Client Secret for Keycloak OAuth2
        scopes: openid, profile, email # Scopes for Keycloak OAuth2
        useAsUsername: preferred_username # Field to use as the username for Keycloak OAuth2
      google:
        clientId: '' # Client ID for Google OAuth2
        clientSecret: '' # Client Secret for Google OAuth2
        scopes: https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile # Scopes for Google OAuth2
        useAsUsername: email # Field to use as the username for Google OAuth2
      github:
        clientId: '' # Client ID for GitHub OAuth2
        clientSecret: '' # Client Secret for GitHub OAuth2
        scopes: read:user # Scope for GitHub OAuth2
        useAsUsername: login # Field to use as the username for GitHub OAuth2
    issuer: '' # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point
    clientId: '' # Client ID from your provider
    clientSecret: '' # Client Secret from your provider
    autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users
    blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin
    useAsUsername: email # Default is 'email'; custom fields can be used as the username
    scopes: openid, profile, email # Specify the scopes for which the application will request permissions
    provider: google # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak'
system:
  defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc)
  googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow
  enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes)
  showUpdate: true # see when a new update is available
  showUpdateOnlyAdmin: false # Only admins can see when a new update is available, depending on showUpdate it must be set to 'true'
  customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template html files
ui:
  appName: '' # Application's visible name
  homeDescription: '' # Short description or tagline shown on homepage.
  appNameNavbar: '' # Name displayed on the navigation bar
endpoints:
  toRemove: [] # List endpoints to disable (e.g. ['img-to-pdf', 'remove-pages'])
  groupsToRemove: [] # List groups to disable (e.g. ['LibreOffice'])
metrics:
  enabled: true # 'true' to enable Info APIs (`/api/*`) endpoints, 'false' to disable

There is an additional config file /configs/custom_settings.yml were users familiar with java and spring application.properties can input their own settings on-top of Stirling-PDFs existing ones

Extra notes

  • Endpoints. Currently, the endpoints ENDPOINTS_TO_REMOVE and GROUPS_TO_REMOVE can include comma separate lists of endpoints and groups to disable as example ENDPOINTS_TO_REMOVE=img-to-pdf,remove-pages would disable both image-to-pdf and remove pages, GROUPS_TO_REMOVE=LibreOffice Would disable all things that use LibreOffice. You can see a list of all endpoints and groups here
  • customStaticFilePath. Customise static files such as the app logo by placing files in the /customFiles/static/ directory. An example of customising app logo is placing a /customFiles/static/favicon.svg to override current SVG. This can be used to change any images/icons/css/fonts/js etc in Stirling-PDF

Environment only parameters

  • SYSTEM_ROOTURIPATH ie set to /pdf-app to Set the application's root URI to localhost:8080/pdf-app
  • SYSTEM_CONNECTIONTIMEOUTMINUTES to set custom connection timeout values
  • DOCKER_ENABLE_SECURITY to tell docker to download security jar (required as true for auth login)
  • INSTALL_BOOK_AND_ADVANCED_HTML_OPS to download calibre onto stirling-pdf enabling pdf to/from book and advanced html conversion
  • LANGS to define custom font libraries to install for use for document conversions

API

For those wanting to use Stirling-PDFs backend API to link with their own custom scripting to edit PDFs you can view all existing API documentation here or navigate to /swagger-ui/index.html of your stirling-pdf instance for your versions documentation (Or by following the API button in your settings of Stirling-PDF)

Login authentication

stirling-login

Prerequisites

  • User must have the folder ./configs volumed within docker so that it is retained during updates.
  • Docker users must download the security jar version by setting DOCKER_ENABLE_SECURITY to true in environment variables.
  • Then either enable login via the settings.yml file or via setting SECURITY_ENABLE_LOGIN to true
  • Now the initial user will be generated with username admin and password stirling. On login you will be forced to change the password to a new one. You can also use the environment variables SECURITY_INITIALLOGIN_USERNAME and SECURITY_INITIALLOGIN_PASSWORD to set your own straight away (Recommended to remove them after user creation).

Once the above has been done, on restart, a new stirling-pdf-DB.mv.db will show if everything worked.

When you login to Stirling PDF you will be redirected to /login page to login with those default credentials. After login everything should function as normal

To access your account settings go to Account settings in the settings cog menu (top right in navbar) This Account settings menu is also where you find your API key.

To add new users go to the bottom of Account settings and hit 'Admin Settings', here you can add new users. The different roles mentioned within this are for rate limiting. This is a Work in progress which will be expanding on more in future

For API usage you must provide a header with 'X-API-Key' and the associated API key for that user.

FAQ

Q1: What are your planned features?

  • Progress bar/Tracking
  • Full custom logic pipelines to combine multiple operations together.
  • Folder support with auto scanning to perform operations on
  • Redact text (Via UI not just automated way)
  • Add Forms
  • Multi page layout (Stich PDF pages together) support x rows y columns and custom page sizing
  • Fill forms manually or automatically

Q2: Why is my application downloading .htm files?

This is an issue caused commonly by your NGINX configuration. The default file upload size for NGINX is 1MB, you need to add the following in your Nginx sites-available file. client_max_body_size SIZE; Where "SIZE" is 50M for example for 50MB files.

Q3: Why is my download timing out

NGINX has timeout values by default so if you are running Stirling-PDF behind NGINX you may need to set a timeout value such as adding the config proxy_read_timeout 3600;

{
"by": "gitinit",
"descendants": 103,
"id": 40242639,
"kids": [
40248518,
40245096,
40243860,
40245090,
40248677,
40244627,
40244802,
40244283,
40257670,
40251549,
40245064,
40249772,
40245036,
40245545,
40248252,
40244366,
40250919,
40260227,
40245614,
40248339,
40249631,
40244320,
40244977,
40244481,
40257161,
40255460
],
"score": 366,
"time": 1714694168,
"title": "Stirling PDF: Self-hosted, web-based PDF manipulation tool",
"type": "story",
"url": "https://github.com/Stirling-Tools/Stirling-PDF"
}
{
"author": "Stirling-Tools",
"date": null,
"description": "#1 Locally hosted web application that allows you to perform various operations on PDF files - Stirling-Tools/Stirling-PDF",
"image": "https://opengraph.githubassets.com/7361d0f5ffcdd9b9b950def2b9114204341c774bd65664c4222a19cbade28284/Stirling-Tools/Stirling-PDF",
"logo": "https://logo.clearbit.com/github.com",
"publisher": "GitHub",
"title": "GitHub - Stirling-Tools/Stirling-PDF: #1 Locally hosted web application that allows you to perform various operations on PDF files",
"url": "https://github.com/Stirling-Tools/Stirling-PDF"
}
{
"url": "https://github.com/Stirling-Tools/Stirling-PDF",
"title": "GitHub - Stirling-Tools/Stirling-PDF: #1 Locally hosted web application that allows you to perform various operations on PDF files",
"description": "Stirling-PDF This is a robust, locally hosted web-based PDF manipulation tool using Docker. It enables you to carry out various operations on PDF files, including splitting, merging, converting,...",
"links": [
"https://github.com/Stirling-Tools/Stirling-PDF"
],
"image": "https://opengraph.githubassets.com/7361d0f5ffcdd9b9b950def2b9114204341c774bd65664c4222a19cbade28284/Stirling-Tools/Stirling-PDF",
"content": "<div><article><p><a target=\"_blank\" href=\"https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/main/docs/stirling.png\"><img src=\"https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/main/docs/stirling.png\" /></a></p>\n<p></p><h2>Stirling-PDF</h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#stirling-pdf\"></a><p></p>\n<p><a target=\"_blank\" href=\"https://hub.docker.com/r/frooodle/s-pdf\"><img src=\"https://camo.githubusercontent.com/c68b933d6eafffa5c71f4f92d01bb7d918310b575f43c10960491705418d1aba/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f70756c6c732f66726f6f6f646c652f732d706466\" alt=\"Docker Pulls\" /></a>\n<a target=\"_blank\" href=\"https://discord.gg/Cn8pWhQRxZ\"><img src=\"https://camo.githubusercontent.com/a6777816cb818db7b9e2b0a943d092cf5bd8e9722c9b00e3fef2ced495a80033/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f313036383633363734383831343438333731383f6c6162656c3d446973636f7264\" alt=\"Discord\" /></a>\n<a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF/\"><img src=\"https://camo.githubusercontent.com/b5bdb2bff34690d051c736c8d027c5d22e6485a4f37f68a3a3691472d320237f/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f762f66726f6f6f646c652f732d7064662f6c6174657374\" alt=\"Docker Image Version (tag latest semver)\" /></a>\n<a target=\"_blank\" href=\"https://github.com/Stirling-Tools/stirling-pdf\"><img src=\"https://camo.githubusercontent.com/ebad192820af71ef9823325d65866f77adc4d990f6f92a1f2fb7251965526026/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f737469726c696e672d746f6f6c732f737469726c696e672d7064663f7374796c653d736f6369616c\" alt=\"GitHub Repo stars\" /></a></p>\n<p><a target=\"_blank\" href=\"https://cloud.digitalocean.com/apps/new?repo=https://github.com/Stirling-Tools/Stirling-PDF/tree/digitalOcean&amp;refcode=c3210994b1af\"><img src=\"https://camo.githubusercontent.com/e093a0ed531124a715aad44362848ca2cff28c3182c2c0ca4a70b2564b681f59/68747470733a2f2f7777772e6465706c6f79746f646f2e636f6d2f646f2d62746e2d626c75652e737667\" alt=\"Deploy to DO\" /></a>\n<a target=\"_blank\" href=\"https://www.ssdnodes.com/manage/aff.php?aff=2216&amp;register=true\"><img src=\"https://camo.githubusercontent.com/2224389a150505fca98fc4d7f3c48652a64662cc7987a7f3c576106f2459d386/68747470733a2f2f7777772e7373646e6f6465732e636f6d2f77702d636f6e74656e742f75706c6f6164732f323032332f31312f666f6f7465722d6c6f676f2e737667\" alt=\"Name\" /></a></p>\n<p>This is a robust, locally hosted web-based PDF manipulation tool using Docker. It enables you to carry out various operations on PDF files, including splitting, merging, converting, reorganizing, adding images, rotating, compressing, and more. This locally hosted web application has evolved to encompass a comprehensive set of features, addressing all your PDF requirements.</p>\n<p>Stirling PDF does not initiate any outbound calls for record-keeping or tracking purposes.</p>\n<p>All files and PDFs exist either exclusively on the client side, reside in server memory only during task execution, or temporarily reside in a file solely for the execution of the task. Any file downloaded by the user will have been deleted from the server by that point.</p>\n<p><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF/blob/main/images/stirling-home.jpg\"><img src=\"https://github.com/Stirling-Tools/Stirling-PDF/raw/main/images/stirling-home.jpg\" alt=\"stirling-home\" /></a></p>\n<p></p><h2>Features</h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#features\"></a><p></p>\n<ul>\n<li>Dark mode support.</li>\n<li>Custom download options</li>\n<li>Parallel file processing and downloads</li>\n<li>Custom 'Pipelines' to run multiple features in a queue</li>\n<li>API for integration with external scripts</li>\n<li>Optional Login and Authentication support (see <a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF/tree/main#login-authentication\">here</a> for documentation)</li>\n<li>Database Backup and Import (see <a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DATABASE.md\">here</a> for documentation)</li>\n</ul>\n<p></p><h2><strong>PDF Features</strong></h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#pdf-features\"></a><p></p>\n<p></p><h3><strong>Page Operations</strong></h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#page-operations\"></a><p></p>\n<ul>\n<li>View and modify PDFs - View multi page PDFs with custom viewing sorting and searching. Plus on page edit features like annotate, draw and adding text and images. (Using PDF.js with Joxit and Liberation.Liberation fonts)</li>\n<li>Full interactive GUI for merging/splitting/rotating/moving PDFs and their pages.</li>\n<li>Merge multiple PDFs together into a single resultant file.</li>\n<li>Split PDFs into multiple files at specified page numbers or extract all pages as individual files.</li>\n<li>Reorganize PDF pages into different orders.</li>\n<li>Rotate PDFs in 90-degree increments.</li>\n<li>Remove pages.</li>\n<li>Multi-page layout (Format PDFs into a multi-paged page).</li>\n<li>Scale page contents size by set %.</li>\n<li>Adjust Contrast.</li>\n<li>Crop PDF.</li>\n<li>Auto Split PDF (With physically scanned page dividers).</li>\n<li>Extract page(s).</li>\n<li>Convert PDF to a single page.</li>\n<li>Overlay PDFs ontop of each other</li>\n</ul>\n<p></p><h3><strong>Conversion Operations</strong></h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#conversion-operations\"></a><p></p>\n<ul>\n<li>Convert PDFs to and from images.</li>\n<li>Convert any common file to PDF (using LibreOffice).</li>\n<li>Convert PDF to Word/Powerpoint/Others (using LibreOffice).</li>\n<li>Convert HTML to PDF.</li>\n<li>URL to PDF.</li>\n<li>Markdown to PDF.</li>\n</ul>\n<p></p><h3><strong>Security &amp; Permissions</strong></h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#security--permissions\"></a><p></p>\n<ul>\n<li>Add and remove passwords.</li>\n<li>Change/set PDF Permissions.</li>\n<li>Add watermark(s).</li>\n<li>Certify/sign PDFs.</li>\n<li>Sanitize PDFs.</li>\n<li>Auto-redact text.</li>\n</ul>\n<p></p><h3><strong>Other Operations</strong></h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#other-operations\"></a><p></p>\n<ul>\n<li>Add/Generate/Write signatures.</li>\n<li>Repair PDFs.</li>\n<li>Detect and remove blank pages.</li>\n<li>Compare 2 PDFs and show differences in text.</li>\n<li>Add images to PDFs.</li>\n<li>Compress PDFs to decrease their filesize (Using OCRMyPDF).</li>\n<li>Extract images from PDF.</li>\n<li>Extract images from Scans.</li>\n<li>Add page numbers.</li>\n<li>Auto rename file by detecting PDF header text.</li>\n<li>OCR on PDF (Using OCRMyPDF).</li>\n<li>PDF/A conversion (Using OCRMyPDF).</li>\n<li>Edit metadata.</li>\n<li>Flatten PDFs.</li>\n<li>Get all information on a PDF to view or export as JSON.</li>\n<li>Show/Detect embedded Javascript</li>\n</ul>\n<p>For a overview of the tasks and the technology each uses please view <a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF/blob/main/Endpoint-groups.md\">Endpoint-groups.md</a></p>\n<p>Demo of the app is available <a target=\"_blank\" href=\"https://stirlingpdf.io/\">here</a>.</p>\n<p></p><h2>Technologies used</h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#technologies-used\"></a><p></p>\n<ul>\n<li>Spring Boot + Thymeleaf</li>\n<li><a target=\"_blank\" href=\"https://github.com/apache/pdfbox/tree/trunk\">PDFBox</a></li>\n<li><a target=\"_blank\" href=\"https://www.libreoffice.org/discover/libreoffice/\">LibreOffice</a> for advanced conversions</li>\n<li><a target=\"_blank\" href=\"https://github.com/ocrmypdf/OCRmyPDF\">OcrMyPdf</a></li>\n<li>HTML, CSS, JavaScript</li>\n<li>Docker</li>\n<li><a target=\"_blank\" href=\"https://github.com/mozilla/pdf.js\">PDF.js</a></li>\n<li><a target=\"_blank\" href=\"https://github.com/Hopding/pdf-lib\">PDF-LIB.js</a></li>\n</ul>\n<p></p><h2>How to use</h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#how-to-use\"></a><p></p>\n<p></p><h3>Locally</h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#locally\"></a><p></p>\n<p>Please view <a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF/blob/main/LocalRunGuide.md\">https://github.com/Stirling-Tools/Stirling-PDF/blob/main/LocalRunGuide.md</a></p>\n<p></p><h3>Docker / Podman</h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#docker--podman\"></a><p></p>\n<p><a target=\"_blank\" href=\"https://hub.docker.com/r/frooodle/s-pdf\">https://hub.docker.com/r/frooodle/s-pdf</a></p>\n<p>Stirling PDF has 3 different versions, a Full version and ultra-Lite version as well as a 'Fat' version. Depending on the types of features you use you may want a smaller image to save on space.\nTo see what the different versions offer please look at our <a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF/blob/main/Version-groups.md\">version mapping</a>\nFor people that don't mind about space optimization just use the latest tag.\n<a target=\"_blank\" href=\"https://camo.githubusercontent.com/9da96226401e6ed81fee45bbeba388930ce9a19e39104186bcefc385276dabb5/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f696d6167652d73697a652f66726f6f6f646c652f732d7064662f6c61746573743f6c6162656c3d537469726c696e672d50444625323046756c6c\"><img src=\"https://camo.githubusercontent.com/9da96226401e6ed81fee45bbeba388930ce9a19e39104186bcefc385276dabb5/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f696d6167652d73697a652f66726f6f6f646c652f732d7064662f6c61746573743f6c6162656c3d537469726c696e672d50444625323046756c6c\" alt=\"Docker Image Size (tag)\" /></a>\n<a target=\"_blank\" href=\"https://camo.githubusercontent.com/88afe16171025aedfde9965bcfba30c1853fcc5f6aa5d5c160627b0f88330ca6/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f696d6167652d73697a652f66726f6f6f646c652f732d7064662f6c61746573742d756c7472612d6c6974653f6c6162656c3d537469726c696e672d504446253230556c7472612d4c697465\"><img src=\"https://camo.githubusercontent.com/88afe16171025aedfde9965bcfba30c1853fcc5f6aa5d5c160627b0f88330ca6/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f696d6167652d73697a652f66726f6f6f646c652f732d7064662f6c61746573742d756c7472612d6c6974653f6c6162656c3d537469726c696e672d504446253230556c7472612d4c697465\" alt=\"Docker Image Size (tag)\" /></a>\n<a target=\"_blank\" href=\"https://camo.githubusercontent.com/127add41d1317e29ec8c83cfe23a9ddbdca83b7e93b7d7a184c578290e0026e2/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f696d6167652d73697a652f66726f6f6f646c652f732d7064662f6c61746573742d6661743f6c6162656c3d537469726c696e672d504446253230466174\"><img src=\"https://camo.githubusercontent.com/127add41d1317e29ec8c83cfe23a9ddbdca83b7e93b7d7a184c578290e0026e2/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f696d6167652d73697a652f66726f6f6f646c652f732d7064662f6c61746573742d6661743f6c6162656c3d537469726c696e672d504446253230466174\" alt=\"Docker Image Size (tag)\" /></a></p>\n<p>Please note in below examples you may need to change the volume paths as needed, current examples install them to the current working directory\neg <code>./extraConfigs:/configs</code> to <code>/opt/stirlingpdf/extraConfigs:/configs</code></p>\n<p></p><h3>Docker Run</h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#docker-run\"></a><p></p>\n<div><pre>docker run -d \\\n -p 8080:8080 \\\n -v ./trainingData:/usr/share/tessdata \\\n -v ./extraConfigs:/configs \\\n -v ./logs:/logs \\\n -e DOCKER_ENABLE_SECURITY=false \\\n -e INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false \\\n -e LANGS=en_GB \\\n --name stirling-pdf \\\n frooodle/s-pdf:latest\n Can also add these <span>for</span> customisation but are not required\n -v /location/of/customFiles:/customFiles \\</pre></div>\n<p></p><h3>Docker Compose</h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#docker-compose\"></a><p></p>\n<div><pre><span>version</span>: <span><span>'</span>3.3<span>'</span></span>\n<span>services</span>:\n <span>stirling-pdf</span>:\n <span>image</span>: <span>frooodle/s-pdf:latest</span>\n <span>ports</span>:\n - <span><span>'</span>8080:8080<span>'</span></span>\n <span>volumes</span>:\n - <span>./trainingData:/usr/share/tessdata </span><span><span>#</span>Required for extra OCR languages</span>\n - <span>./extraConfigs:/configs</span>\n<span><span>#</span> - ./customFiles:/customFiles/</span>\n<span><span>#</span> - ./logs:/logs/</span>\n <span>environment</span>:\n - <span>DOCKER_ENABLE_SECURITY=false</span>\n - <span>INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false</span>\n - <span>LANGS=en_GB</span></pre></div>\n<p>Note: Podman is CLI-compatible with Docker, so simply replace \"docker\" with \"podman\".</p>\n<p></p><h2>Enable OCR/Compression feature</h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#enable-ocrcompression-feature\"></a><p></p>\n<p>Please view <a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToUseOCR.md\">https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToUseOCR.md</a></p>\n<p></p><h2>Supported Languages</h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#supported-languages\"></a><p></p>\n<p>Stirling PDF currently supports 38!</p>\n<table>\n<thead>\n<tr>\n<th>Language</th>\n<th>Progress</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Arabic (العربية) (ar_AR)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/2f8a9dc112e69d20f5f0039073e766f1c4791af5b7000779400977e009d2653a/68747470733a2f2f676570732e6465762f70726f67726573732f313030\"><img src=\"https://camo.githubusercontent.com/2f8a9dc112e69d20f5f0039073e766f1c4791af5b7000779400977e009d2653a/68747470733a2f2f676570732e6465762f70726f67726573732f313030\" alt=\"100%\" /></a></td>\n</tr>\n<tr>\n<td>Basque (Euskara) (eu_ES)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/fc11b0f55f00b9e8b1f0e40b1fba1991e1fea556072f459cd28614d7a8338f11/68747470733a2f2f676570732e6465762f70726f67726573732f3630\"><img src=\"https://camo.githubusercontent.com/fc11b0f55f00b9e8b1f0e40b1fba1991e1fea556072f459cd28614d7a8338f11/68747470733a2f2f676570732e6465762f70726f67726573732f3630\" alt=\"60%\" /></a></td>\n</tr>\n<tr>\n<td>Bulgarian (Български) (bg_BG)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/1de98c0383ed4ed6d18e685941e62799f2fc5abaa03b27f7a8bd7644059cd93e/68747470733a2f2f676570732e6465762f70726f67726573732f3932\"><img src=\"https://camo.githubusercontent.com/1de98c0383ed4ed6d18e685941e62799f2fc5abaa03b27f7a8bd7644059cd93e/68747470733a2f2f676570732e6465762f70726f67726573732f3932\" alt=\"92%\" /></a></td>\n</tr>\n<tr>\n<td>Catalan (Català) (ca_CA)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/6d70b9fc3a1724bdcaa4a42269572add79e4f4102a51e779f1836269fce8c76a/68747470733a2f2f676570732e6465762f70726f67726573732f3437\"><img src=\"https://camo.githubusercontent.com/6d70b9fc3a1724bdcaa4a42269572add79e4f4102a51e779f1836269fce8c76a/68747470733a2f2f676570732e6465762f70726f67726573732f3437\" alt=\"47%\" /></a></td>\n</tr>\n<tr>\n<td>Croatian (Hrvatski) (hr_HR)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/1de98c0383ed4ed6d18e685941e62799f2fc5abaa03b27f7a8bd7644059cd93e/68747470733a2f2f676570732e6465762f70726f67726573732f3932\"><img src=\"https://camo.githubusercontent.com/1de98c0383ed4ed6d18e685941e62799f2fc5abaa03b27f7a8bd7644059cd93e/68747470733a2f2f676570732e6465762f70726f67726573732f3932\" alt=\"92%\" /></a></td>\n</tr>\n<tr>\n<td>Czech (Česky) (cs_CZ)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/ed026a0e5bf05d76bb4f338ed0bcbd93618ffad451afd5881017b0015ed7afb9/68747470733a2f2f676570732e6465762f70726f67726573732f3838\"><img src=\"https://camo.githubusercontent.com/ed026a0e5bf05d76bb4f338ed0bcbd93618ffad451afd5881017b0015ed7afb9/68747470733a2f2f676570732e6465762f70726f67726573732f3838\" alt=\"88%\" /></a></td>\n</tr>\n<tr>\n<td>Danish (Dansk) (da_DK)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/8d52d2df945fe2e4d72114541c8499accd7e6c0e9e69be57c9a2ca61569a5c8d/68747470733a2f2f676570732e6465762f70726f67726573732f3937\"><img src=\"https://camo.githubusercontent.com/8d52d2df945fe2e4d72114541c8499accd7e6c0e9e69be57c9a2ca61569a5c8d/68747470733a2f2f676570732e6465762f70726f67726573732f3937\" alt=\"97%\" /></a></td>\n</tr>\n<tr>\n<td>Dutch (Nederlands) (nl_NL)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/5dedc1c8410c82cbcf038f4dfc27eb6e400a072b9edb9a024cda6e88e420a97e/68747470733a2f2f676570732e6465762f70726f67726573732f3933\"><img src=\"https://camo.githubusercontent.com/5dedc1c8410c82cbcf038f4dfc27eb6e400a072b9edb9a024cda6e88e420a97e/68747470733a2f2f676570732e6465762f70726f67726573732f3933\" alt=\"93%\" /></a></td>\n</tr>\n<tr>\n<td>English (English) (en_GB)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/2f8a9dc112e69d20f5f0039073e766f1c4791af5b7000779400977e009d2653a/68747470733a2f2f676570732e6465762f70726f67726573732f313030\"><img src=\"https://camo.githubusercontent.com/2f8a9dc112e69d20f5f0039073e766f1c4791af5b7000779400977e009d2653a/68747470733a2f2f676570732e6465762f70726f67726573732f313030\" alt=\"100%\" /></a></td>\n</tr>\n<tr>\n<td>English (US) (en_US)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/2f8a9dc112e69d20f5f0039073e766f1c4791af5b7000779400977e009d2653a/68747470733a2f2f676570732e6465762f70726f67726573732f313030\"><img src=\"https://camo.githubusercontent.com/2f8a9dc112e69d20f5f0039073e766f1c4791af5b7000779400977e009d2653a/68747470733a2f2f676570732e6465762f70726f67726573732f313030\" alt=\"100%\" /></a></td>\n</tr>\n<tr>\n<td>French (Français) (fr_FR)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/f65bb7a617de14336220fc288562d5ec8158551ea269a9bd9698a45f4a5fb13e/68747470733a2f2f676570732e6465762f70726f67726573732f3931\"><img src=\"https://camo.githubusercontent.com/f65bb7a617de14336220fc288562d5ec8158551ea269a9bd9698a45f4a5fb13e/68747470733a2f2f676570732e6465762f70726f67726573732f3931\" alt=\"91%\" /></a></td>\n</tr>\n<tr>\n<td>German (Deutsch) (de_DE)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/8a2f2df7b116aacbe6c7cf843192cf4a0ad4fcc344653ca3caefb685e6fdbdfe/68747470733a2f2f676570732e6465762f70726f67726573732f3939\"><img src=\"https://camo.githubusercontent.com/8a2f2df7b116aacbe6c7cf843192cf4a0ad4fcc344653ca3caefb685e6fdbdfe/68747470733a2f2f676570732e6465762f70726f67726573732f3939\" alt=\"99%\" /></a></td>\n</tr>\n<tr>\n<td>Greek (Ελληνικά) (el_GR)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/4a31f73f8f49ecb444aed6093d878d9a04aaf9bbbaa8de40df50b22b0edd0986/68747470733a2f2f676570732e6465762f70726f67726573732f3830\"><img src=\"https://camo.githubusercontent.com/4a31f73f8f49ecb444aed6093d878d9a04aaf9bbbaa8de40df50b22b0edd0986/68747470733a2f2f676570732e6465762f70726f67726573732f3830\" alt=\"80%\" /></a></td>\n</tr>\n<tr>\n<td>Hindi (हिंदी) (hi_IN)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/72f0777645327fd0c12ac9a5a35fc443c586de2fb9fb0de290fde4a4b534926a/68747470733a2f2f676570732e6465762f70726f67726573732f3736\"><img src=\"https://camo.githubusercontent.com/72f0777645327fd0c12ac9a5a35fc443c586de2fb9fb0de290fde4a4b534926a/68747470733a2f2f676570732e6465762f70726f67726573732f3736\" alt=\"76%\" /></a></td>\n</tr>\n<tr>\n<td>Hungarian (Magyar) (hu_HU)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/7f0bd46c90107b1a678ebcc67691b2badfed5d87f68f77d9a779985aa762276a/68747470733a2f2f676570732e6465762f70726f67726573732f3733\"><img src=\"https://camo.githubusercontent.com/7f0bd46c90107b1a678ebcc67691b2badfed5d87f68f77d9a779985aa762276a/68747470733a2f2f676570732e6465762f70726f67726573732f3733\" alt=\"73%\" /></a></td>\n</tr>\n<tr>\n<td>Indonesia (Bahasa Indonesia) (id_ID)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/cc05a3982d88e0af90dee1408a5c14959fc2722025737ef035845cf763b19b36/68747470733a2f2f676570732e6465762f70726f67726573732f3734\"><img src=\"https://camo.githubusercontent.com/cc05a3982d88e0af90dee1408a5c14959fc2722025737ef035845cf763b19b36/68747470733a2f2f676570732e6465762f70726f67726573732f3734\" alt=\"74%\" /></a></td>\n</tr>\n<tr>\n<td>Irish (Gaeilge) (ga_IE)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/57adcb0b8bad527739df86818eb2590bdfb2377e0d290c7bcdd99726b95b65c9/68747470733a2f2f676570732e6465762f70726f67726573732f3936\"><img src=\"https://camo.githubusercontent.com/57adcb0b8bad527739df86818eb2590bdfb2377e0d290c7bcdd99726b95b65c9/68747470733a2f2f676570732e6465762f70726f67726573732f3936\" alt=\"96%\" /></a></td>\n</tr>\n<tr>\n<td>Italian (Italiano) (it_IT)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/8a2f2df7b116aacbe6c7cf843192cf4a0ad4fcc344653ca3caefb685e6fdbdfe/68747470733a2f2f676570732e6465762f70726f67726573732f3939\"><img src=\"https://camo.githubusercontent.com/8a2f2df7b116aacbe6c7cf843192cf4a0ad4fcc344653ca3caefb685e6fdbdfe/68747470733a2f2f676570732e6465762f70726f67726573732f3939\" alt=\"99%\" /></a></td>\n</tr>\n<tr>\n<td>Japanese (日本語) (ja_JP)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/0a7f1d51fa185e81e9c0ced54cbb3e1f8feab5ff4567137dff5e64a856b2d810/68747470733a2f2f676570732e6465762f70726f67726573732f3930\"><img src=\"https://camo.githubusercontent.com/0a7f1d51fa185e81e9c0ced54cbb3e1f8feab5ff4567137dff5e64a856b2d810/68747470733a2f2f676570732e6465762f70726f67726573732f3930\" alt=\"90%\" /></a></td>\n</tr>\n<tr>\n<td>Korean (한국어) (ko_KR)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/14d5869d66c55096fc3d3d2c3fc0a6c8d8328d90196fc67be7407cde9fc1d782/68747470733a2f2f676570732e6465762f70726f67726573732f3832\"><img src=\"https://camo.githubusercontent.com/14d5869d66c55096fc3d3d2c3fc0a6c8d8328d90196fc67be7407cde9fc1d782/68747470733a2f2f676570732e6465762f70726f67726573732f3832\" alt=\"82%\" /></a></td>\n</tr>\n<tr>\n<td>Norwegian (Norsk) (no_NB)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/3c71e823b83be6b7860fa27a83b46423a3d784bb9556613bc23483b92958842a/68747470733a2f2f676570732e6465762f70726f67726573732f3935\"><img src=\"https://camo.githubusercontent.com/3c71e823b83be6b7860fa27a83b46423a3d784bb9556613bc23483b92958842a/68747470733a2f2f676570732e6465762f70726f67726573732f3935\" alt=\"95%\" /></a></td>\n</tr>\n<tr>\n<td>Polish (Polski) (pl_PL)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/0a7f1d51fa185e81e9c0ced54cbb3e1f8feab5ff4567137dff5e64a856b2d810/68747470733a2f2f676570732e6465762f70726f67726573732f3930\"><img src=\"https://camo.githubusercontent.com/0a7f1d51fa185e81e9c0ced54cbb3e1f8feab5ff4567137dff5e64a856b2d810/68747470733a2f2f676570732e6465762f70726f67726573732f3930\" alt=\"90%\" /></a></td>\n</tr>\n<tr>\n<td>Portuguese (Português) (pt_PT)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/72f0777645327fd0c12ac9a5a35fc443c586de2fb9fb0de290fde4a4b534926a/68747470733a2f2f676570732e6465762f70726f67726573732f3736\"><img src=\"https://camo.githubusercontent.com/72f0777645327fd0c12ac9a5a35fc443c586de2fb9fb0de290fde4a4b534926a/68747470733a2f2f676570732e6465762f70726f67726573732f3736\" alt=\"76%\" /></a></td>\n</tr>\n<tr>\n<td>Portuguese Brazilian (Português) (pt_BR)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/8a2f2df7b116aacbe6c7cf843192cf4a0ad4fcc344653ca3caefb685e6fdbdfe/68747470733a2f2f676570732e6465762f70726f67726573732f3939\"><img src=\"https://camo.githubusercontent.com/8a2f2df7b116aacbe6c7cf843192cf4a0ad4fcc344653ca3caefb685e6fdbdfe/68747470733a2f2f676570732e6465762f70726f67726573732f3939\" alt=\"99%\" /></a></td>\n</tr>\n<tr>\n<td>Romanian (Română) (ro_RO)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/eddafe01ad01111857f48c0e51949b35fccfb298f62d5d06c87885a4658e52ec/68747470733a2f2f676570732e6465762f70726f67726573732f3938\"><img src=\"https://camo.githubusercontent.com/eddafe01ad01111857f48c0e51949b35fccfb298f62d5d06c87885a4658e52ec/68747470733a2f2f676570732e6465762f70726f67726573732f3938\" alt=\"98%\" /></a></td>\n</tr>\n<tr>\n<td>Russian (Русский) (ru_RU)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/14d5869d66c55096fc3d3d2c3fc0a6c8d8328d90196fc67be7407cde9fc1d782/68747470733a2f2f676570732e6465762f70726f67726573732f3832\"><img src=\"https://camo.githubusercontent.com/14d5869d66c55096fc3d3d2c3fc0a6c8d8328d90196fc67be7407cde9fc1d782/68747470733a2f2f676570732e6465762f70726f67726573732f3832\" alt=\"82%\" /></a></td>\n</tr>\n<tr>\n<td>Serbian Latin alphabet (Srpski) (sr_LATN_RS)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/72f0777645327fd0c12ac9a5a35fc443c586de2fb9fb0de290fde4a4b534926a/68747470733a2f2f676570732e6465762f70726f67726573732f3736\"><img src=\"https://camo.githubusercontent.com/72f0777645327fd0c12ac9a5a35fc443c586de2fb9fb0de290fde4a4b534926a/68747470733a2f2f676570732e6465762f70726f67726573732f3736\" alt=\"76%\" /></a></td>\n</tr>\n<tr>\n<td>Simplified Chinese (简体中文) (zh_CN)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/57adcb0b8bad527739df86818eb2590bdfb2377e0d290c7bcdd99726b95b65c9/68747470733a2f2f676570732e6465762f70726f67726573732f3936\"><img src=\"https://camo.githubusercontent.com/57adcb0b8bad527739df86818eb2590bdfb2377e0d290c7bcdd99726b95b65c9/68747470733a2f2f676570732e6465762f70726f67726573732f3936\" alt=\"96%\" /></a></td>\n</tr>\n<tr>\n<td>Slovakian (Slovensky) (sk_SK)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/0a7f1d51fa185e81e9c0ced54cbb3e1f8feab5ff4567137dff5e64a856b2d810/68747470733a2f2f676570732e6465762f70726f67726573732f3930\"><img src=\"https://camo.githubusercontent.com/0a7f1d51fa185e81e9c0ced54cbb3e1f8feab5ff4567137dff5e64a856b2d810/68747470733a2f2f676570732e6465762f70726f67726573732f3930\" alt=\"90%\" /></a></td>\n</tr>\n<tr>\n<td>Spanish (Español) (es_ES)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/8a2f2df7b116aacbe6c7cf843192cf4a0ad4fcc344653ca3caefb685e6fdbdfe/68747470733a2f2f676570732e6465762f70726f67726573732f3939\"><img src=\"https://camo.githubusercontent.com/8a2f2df7b116aacbe6c7cf843192cf4a0ad4fcc344653ca3caefb685e6fdbdfe/68747470733a2f2f676570732e6465762f70726f67726573732f3939\" alt=\"99%\" /></a></td>\n</tr>\n<tr>\n<td>Swedish (Svenska) (sv_SE)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/eddafe01ad01111857f48c0e51949b35fccfb298f62d5d06c87885a4658e52ec/68747470733a2f2f676570732e6465762f70726f67726573732f3938\"><img src=\"https://camo.githubusercontent.com/eddafe01ad01111857f48c0e51949b35fccfb298f62d5d06c87885a4658e52ec/68747470733a2f2f676570732e6465762f70726f67726573732f3938\" alt=\"98%\" /></a></td>\n</tr>\n<tr>\n<td>Thai (ไทย) (th_TH)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/8d52d2df945fe2e4d72114541c8499accd7e6c0e9e69be57c9a2ca61569a5c8d/68747470733a2f2f676570732e6465762f70726f67726573732f3937\"><img src=\"https://camo.githubusercontent.com/8d52d2df945fe2e4d72114541c8499accd7e6c0e9e69be57c9a2ca61569a5c8d/68747470733a2f2f676570732e6465762f70726f67726573732f3937\" alt=\"97%\" /></a></td>\n</tr>\n<tr>\n<td>Traditional Chinese (繁體中文) (zh_TW)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/57adcb0b8bad527739df86818eb2590bdfb2377e0d290c7bcdd99726b95b65c9/68747470733a2f2f676570732e6465762f70726f67726573732f3936\"><img src=\"https://camo.githubusercontent.com/57adcb0b8bad527739df86818eb2590bdfb2377e0d290c7bcdd99726b95b65c9/68747470733a2f2f676570732e6465762f70726f67726573732f3936\" alt=\"96%\" /></a></td>\n</tr>\n<tr>\n<td>Turkish (Türkçe) (tr_TR)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/57adcb0b8bad527739df86818eb2590bdfb2377e0d290c7bcdd99726b95b65c9/68747470733a2f2f676570732e6465762f70726f67726573732f3936\"><img src=\"https://camo.githubusercontent.com/57adcb0b8bad527739df86818eb2590bdfb2377e0d290c7bcdd99726b95b65c9/68747470733a2f2f676570732e6465762f70726f67726573732f3936\" alt=\"96%\" /></a></td>\n</tr>\n<tr>\n<td>Ukrainian (Українська) (uk_UA)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/c3ae53d469234236e0121e86244f9b2a9848350f6dbc72aa4680e8c52975d896/68747470733a2f2f676570732e6465762f70726f67726573732f3837\"><img src=\"https://camo.githubusercontent.com/c3ae53d469234236e0121e86244f9b2a9848350f6dbc72aa4680e8c52975d896/68747470733a2f2f676570732e6465762f70726f67726573732f3837\" alt=\"87%\" /></a></td>\n</tr>\n<tr>\n<td>Vietnamese (Tiếng Việt) (vi_VN)</td>\n<td><a target=\"_blank\" href=\"https://camo.githubusercontent.com/57adcb0b8bad527739df86818eb2590bdfb2377e0d290c7bcdd99726b95b65c9/68747470733a2f2f676570732e6465762f70726f67726573732f3936\"><img src=\"https://camo.githubusercontent.com/57adcb0b8bad527739df86818eb2590bdfb2377e0d290c7bcdd99726b95b65c9/68747470733a2f2f676570732e6465762f70726f67726573732f3936\" alt=\"96%\" /></a></td>\n</tr>\n</tbody>\n</table>\n<p></p><h2>Contributing (creating issues, translations, fixing bugs, etc.)</h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#contributing-creating-issues-translations-fixing-bugs-etc\"></a><p></p>\n<p>Please see our <a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md\">Contributing Guide</a>!</p>\n<p></p><h2>Customisation</h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#customisation\"></a><p></p>\n<p>Stirling PDF allows easy customization of the app.\nIncludes things like</p>\n<ul>\n<li>Custom application name</li>\n<li>Custom slogans, icons, HTML, images CSS etc (via file overrides)</li>\n</ul>\n<p>There are two options for this, either using the generated settings file <code>settings.yml</code>\nThis file is located in the <code>/configs</code> directory and follows standard YAML formatting</p>\n<p>Environment variables are also supported and would override the settings file\nFor example in the settings.yml you have</p>\n<div><pre><span>security</span>:\n <span>enableLogin</span>: <span><span>'</span>true<span>'</span></span></pre></div>\n<p>To have this via an environment variable you would have <code>SECURITY_ENABLELOGIN</code></p>\n<p>The Current list of settings is</p>\n<div><pre><span>security</span>:\n <span>enableLogin</span>: <span>false </span><span><span>#</span> set to 'true' to enable login</span>\n <span>csrfDisabled</span>: <span>true </span><span><span>#</span> Set to 'true' to disable CSRF protection (not recommended for production)</span>\n <span>loginAttemptCount</span>: <span>5</span> <span><span>#</span> lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1</span>\n <span>loginResetTimeMinutes</span>: <span>120</span> <span><span>#</span> lock account for 2 hours after x attempts</span>\n <span>loginMethod</span>: <span>all </span><span><span>#</span> 'all' (Login Username/Password and OAuth2[must be enabled and configured]), 'normal'(only Login with Username/Password) or 'oauth2'(only Login with OAuth2)</span>\n <span>initialLogin</span>:\n <span>username</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Initial username for the first login</span>\n <span>password</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Initial password for the first login</span>\n <span>oauth2</span>:\n <span>enabled</span>: <span>false </span><span><span>#</span> set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work)</span>\n <span>client</span>:\n <span>keycloak</span>:\n <span>issuer</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> URL of the Keycloak realm's OpenID Connect Discovery endpoint</span>\n <span>clientId</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Client ID for Keycloak OAuth2</span>\n <span>clientSecret</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Client Secret for Keycloak OAuth2</span>\n <span>scopes</span>: <span>openid, profile, email </span><span><span>#</span> Scopes for Keycloak OAuth2</span>\n <span>useAsUsername</span>: <span>preferred_username </span><span><span>#</span> Field to use as the username for Keycloak OAuth2</span>\n <span>google</span>:\n <span>clientId</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Client ID for Google OAuth2</span>\n <span>clientSecret</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Client Secret for Google OAuth2</span>\n <span>scopes</span>: <span>https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile </span><span><span>#</span> Scopes for Google OAuth2</span>\n <span>useAsUsername</span>: <span>email </span><span><span>#</span> Field to use as the username for Google OAuth2</span>\n <span>github</span>:\n <span>clientId</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Client ID for GitHub OAuth2</span>\n <span>clientSecret</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Client Secret for GitHub OAuth2</span>\n <span>scopes</span>: <span>read:user </span><span><span>#</span> Scope for GitHub OAuth2</span>\n <span>useAsUsername</span>: <span>login </span><span><span>#</span> Field to use as the username for GitHub OAuth2</span>\n <span>issuer</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point</span>\n <span>clientId</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Client ID from your provider</span>\n <span>clientSecret</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Client Secret from your provider</span>\n <span>autoCreateUser</span>: <span>false </span><span><span>#</span> set to 'true' to allow auto-creation of non-existing users</span>\n <span>blockRegistration</span>: <span>false </span><span><span>#</span> set to 'true' to deny login with SSO without prior registration by an admin</span>\n <span>useAsUsername</span>: <span>email </span><span><span>#</span> Default is 'email'; custom fields can be used as the username</span>\n <span>scopes</span>: <span>openid, profile, email </span><span><span>#</span> Specify the scopes for which the application will request permissions</span>\n <span>provider</span>: <span>google </span><span><span>#</span> Set this to your OAuth provider's name, e.g., 'google' or 'keycloak'</span>\n<span>system</span>:\n <span>defaultLocale</span>: <span><span>'</span>en-US<span>'</span></span> <span><span>#</span> Set the default language (e.g. 'de-DE', 'fr-FR', etc)</span>\n <span>googlevisibility</span>: <span>false </span><span><span>#</span> 'true' to allow Google visibility (via robots.txt), 'false' to disallow</span>\n <span>enableAlphaFunctionality</span>: <span>false </span><span><span>#</span> Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes)</span>\n <span>showUpdate</span>: <span>true </span><span><span>#</span> see when a new update is available</span>\n <span>showUpdateOnlyAdmin</span>: <span>false </span><span><span>#</span> Only admins can see when a new update is available, depending on showUpdate it must be set to 'true'</span>\n <span>customHTMLFiles</span>: <span>false </span><span><span>#</span> enable to have files placed in /customFiles/templates override the existing template html files</span>\n<span>ui</span>:\n <span>appName</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Application's visible name</span>\n <span>homeDescription</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Short description or tagline shown on homepage.</span>\n <span>appNameNavbar</span>: <span><span>'</span><span>'</span></span> <span><span>#</span> Name displayed on the navigation bar</span>\n<span>endpoints</span>:\n <span>toRemove</span>: <span>[] </span><span><span>#</span> List endpoints to disable (e.g. ['img-to-pdf', 'remove-pages'])</span>\n <span>groupsToRemove</span>: <span>[] </span><span><span>#</span> List groups to disable (e.g. ['LibreOffice'])</span>\n<span>metrics</span>:\n <span>enabled</span>: <span>true </span><span><span>#</span> 'true' to enable Info APIs (`/api/*`) endpoints, 'false' to disable</span></pre></div>\n<p>There is an additional config file <code>/configs/custom_settings.yml</code> were users familiar with java and spring application.properties can input their own settings on-top of Stirling-PDFs existing ones</p>\n<p></p><h3>Extra notes</h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#extra-notes\"></a><p></p>\n<ul>\n<li>Endpoints. Currently, the endpoints ENDPOINTS_TO_REMOVE and GROUPS_TO_REMOVE can include comma separate lists of endpoints and groups to disable as example ENDPOINTS_TO_REMOVE=img-to-pdf,remove-pages would disable both image-to-pdf and remove pages, GROUPS_TO_REMOVE=LibreOffice Would disable all things that use LibreOffice. You can see a list of all endpoints and groups <a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF/blob/main/Endpoint-groups.md\">here</a></li>\n<li>customStaticFilePath. Customise static files such as the app logo by placing files in the /customFiles/static/ directory. An example of customising app logo is placing a /customFiles/static/favicon.svg to override current SVG. This can be used to change any images/icons/css/fonts/js etc in Stirling-PDF</li>\n</ul>\n<p></p><h3>Environment only parameters</h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#environment-only-parameters\"></a><p></p>\n<ul>\n<li><code>SYSTEM_ROOTURIPATH</code> ie set to <code>/pdf-app</code> to Set the application's root URI to <code>localhost:8080/pdf-app</code></li>\n<li><code>SYSTEM_CONNECTIONTIMEOUTMINUTES</code> to set custom connection timeout values</li>\n<li><code>DOCKER_ENABLE_SECURITY</code> to tell docker to download security jar (required as true for auth login)</li>\n<li><code>INSTALL_BOOK_AND_ADVANCED_HTML_OPS</code> to download calibre onto stirling-pdf enabling pdf to/from book and advanced html conversion</li>\n<li><code>LANGS</code> to define custom font libraries to install for use for document conversions</li>\n</ul>\n<p></p><h2>API</h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#api\"></a><p></p>\n<p>For those wanting to use Stirling-PDFs backend API to link with their own custom scripting to edit PDFs you can view all existing API documentation\n<a target=\"_blank\" href=\"https://app.swaggerhub.com/apis-docs/Stirling-Tools/Stirling-PDF/\">here</a> or navigate to /swagger-ui/index.html of your stirling-pdf instance for your versions documentation (Or by following the API button in your settings of Stirling-PDF)</p>\n<p></p><h2>Login authentication</h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#login-authentication\"></a><p></p>\n<p><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF/blob/main/images/login-light.png\"><img src=\"https://github.com/Stirling-Tools/Stirling-PDF/raw/main/images/login-light.png\" alt=\"stirling-login\" /></a></p>\n<p></p><h3>Prerequisites</h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#prerequisites\"></a><p></p>\n<ul>\n<li>User must have the folder ./configs volumed within docker so that it is retained during updates.</li>\n<li>Docker users must download the security jar version by setting <code>DOCKER_ENABLE_SECURITY</code> to <code>true</code> in environment variables.</li>\n<li>Then either enable login via the settings.yml file or via setting <code>SECURITY_ENABLE_LOGIN</code> to <code>true</code></li>\n<li>Now the initial user will be generated with username <code>admin</code> and password <code>stirling</code>. On login you will be forced to change the password to a new one. You can also use the environment variables <code>SECURITY_INITIALLOGIN_USERNAME</code> and <code>SECURITY_INITIALLOGIN_PASSWORD</code> to set your own straight away (Recommended to remove them after user creation).</li>\n</ul>\n<p>Once the above has been done, on restart, a new stirling-pdf-DB.mv.db will show if everything worked.</p>\n<p>When you login to Stirling PDF you will be redirected to /login page to login with those default credentials. After login everything should function as normal</p>\n<p>To access your account settings go to Account settings in the settings cog menu (top right in navbar) This Account settings menu is also where you find your API key.</p>\n<p>To add new users go to the bottom of Account settings and hit 'Admin Settings', here you can add new users. The different roles mentioned within this are for rate limiting. This is a Work in progress which will be expanding on more in future</p>\n<p>For API usage you must provide a header with 'X-API-Key' and the associated API key for that user.</p>\n<p></p><h2>FAQ</h2><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#faq\"></a><p></p>\n<p></p><h3>Q1: What are your planned features?</h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#q1-what-are-your-planned-features\"></a><p></p>\n<ul>\n<li>Progress bar/Tracking</li>\n<li>Full custom logic pipelines to combine multiple operations together.</li>\n<li>Folder support with auto scanning to perform operations on</li>\n<li>Redact text (Via UI not just automated way)</li>\n<li>Add Forms</li>\n<li>Multi page layout (Stich PDF pages together) support x rows y columns and custom page sizing</li>\n<li>Fill forms manually or automatically</li>\n</ul>\n<p></p><h3>Q2: Why is my application downloading .htm files?</h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#q2-why-is-my-application-downloading-htm-files\"></a><p></p>\n<p>This is an issue caused commonly by your NGINX configuration. The default file upload size for NGINX is 1MB, you need to add the following in your Nginx sites-available file. <code>client_max_body_size SIZE;</code> Where \"SIZE\" is 50M for example for 50MB files.</p>\n<p></p><h3>Q3: Why is my download timing out</h3><a target=\"_blank\" href=\"https://github.com/Stirling-Tools/Stirling-PDF#q3-why-is-my-download-timing-out\"></a><p></p>\n<p>NGINX has timeout values by default so if you are running Stirling-PDF behind NGINX you may need to set a timeout value such as adding the config <code>proxy_read_timeout 3600;</code></p>\n</article></div>",
"author": "",
"favicon": "https://github.githubassets.com/favicons/favicon.svg",
"source": "github.com",
"published": "",
"ttr": 396,
"type": "object"
}