Self-hosted server

Production checklist

1. Install a login build and pin the version#

  • Use the latest or latest-fat image, the Helm chart, or Stirling-PDF-with-login.jar. See Install with Docker, Install on Kubernetes or Install with Java (JAR).
  • Pin a version tag instead of latest so upgrades happen when you choose.
  • Mount at least /configs and /storage, and /customFiles if you use branding or signature files.
  • Size it from Performance: at least 4 GB of memory (about 6 GB for latest-fat), more for larger teams or with the AI engine on.

2. Secure the admin account#

  • Replace the default admin password at first sign-in, or create your own first admin before the first start. See First login.
  • Keep SECURITY_ENABLELOGIN at its default of true.

3. Serve it over HTTPS#

Behind a reverse proxy or load balancer (most setups):

  • Forward requests to port 8080 with the X-Forwarded-Proto, X-Forwarded-Host and X-Forwarded-Port headers.
  • Accept uploads as large as system.fileUploadLimit (2000 MB by default).
  • Turn off response buffering and allow 30-minute read timeouts for long AI and Processor runs.
  • To serve under a sub-path such as /pdf, set SYSTEM_ROOTURIPATH=/pdf and forward the prefix unchanged.

HTTPS in Stirling PDF itself: put your keystore in configs/ and set server.ssl in custom_settings.yml. See Extra settings.

Then set the public addresses the server hands out in links. backendUrl is required for SAML single sign-on, and frontendUrl is used in invite emails, share links, mobile QR codes and the redirect after SAML sign-in:

yaml
system:
  backendUrl: https://pdf.example.com
  frontendUrl: https://pdf.example.com
bash
SYSTEM_BACKENDURL=https://pdf.example.com
SYSTEM_FRONTENDURL=https://pdf.example.com

Example: nginx#

nginx
server {
    listen 80;
    server_name pdf.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name pdf.example.com;

    ssl_certificate     /etc/ssl/certs/pdf.example.com.crt;
    ssl_certificate_key /etc/ssl/private/pdf.example.com.key;

    client_max_body_size 2000M;    # nginx allows 1 MB by default

    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_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_buffering off;
        proxy_read_timeout 1800s;
        proxy_send_timeout 1800s;
    }
}

4. Set up sign-in and users#

  • Add people in Settings → Workspace → Users → Invite people. Invite by email needs email configuration; otherwise use Create account directly.
  • Connect your identity provider: OAuth2 / OIDC single sign-on works on every plan, SAML single sign-on needs Enterprise.
  • Failed sign-ins lock an account after 5 attempts for 120 minutes (security.loginAttemptCount, security.loginResetTimeMinutes). For IP bans, add Fail2Ban.

5. Decide what users can do#

6. Back up#

  • Back up the whole configs/ folder. It holds your settings, generated keys and the built-in database.
  • The built-in database also writes a nightly backup to configs/backup/db/. Copy those off the server too.
  • Back up storage/. It holds the files users save on the server.
  • Back up customFiles/ if you use it.
  • On Team or Enterprise you can use PostgreSQL instead: see Database.

7. Monitor#

  • Point uptime and load balancer health checks at /api/v1/info/status (after your root path, if you set one). It needs no sign-in.
  • Logs are in logs/, or docker logs stirling-pdf.
  • Team and Enterprise add Prometheus metrics: see Usage monitoring. Enterprise adds Usage Analytics and Audit log under Settings → Monitoring.
  • When something breaks, Diagnostics collects logs and settings into one archive.

8. Plan for load and updates#