Stirling-PDF/docker/unified
Anthony Stirling 1117ce6164
Settings display demo and login fix (#4884)
# Description of Changes
<img width="1569" height="980" alt="image"
src="https://github.com/user-attachments/assets/dca1c227-ed84-4393-97a1-e3ce6eb1620b"
/>

<img width="1596" height="935" alt="image"
src="https://github.com/user-attachments/assets/2003e1be-034a-4cbb-869e-6d5d912ab61d"
/>

<img width="1543" height="997" alt="image"
src="https://github.com/user-attachments/assets/fe0c4f4b-eeee-4db4-a041-e554f350255a"
/>


---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-11-14 13:02:45 +00:00
..
build.sh docker (#4711) 2025-10-27 16:45:18 +00:00
entrypoint.sh docker (#4711) 2025-10-27 16:45:18 +00:00
nginx.conf Settings display demo and login fix (#4884) 2025-11-14 13:02:45 +00:00
README.md docker (#4711) 2025-10-27 16:45:18 +00:00

Stirling-PDF Unified Container

Single Docker container that can run as frontend + backend, frontend only, or backend only using the MODE environment variable.

Quick Start

MODE=BOTH (Default)

Single container with both frontend and backend on port 8080:

docker run -p 8080:8080 \
  -e MODE=BOTH \
  stirlingtools/stirling-pdf:unified

Access at: http://localhost:8080

MODE=FRONTEND

Frontend only, connecting to separate backend:

docker run -p 8080:8080 \
  -e MODE=FRONTEND \
  -e VITE_API_BASE_URL=http://backend:8080 \
  stirlingtools/stirling-pdf:unified

MODE=BACKEND

Backend API only:

docker run -p 8080:8080 \
  -e MODE=BACKEND \
  stirlingtools/stirling-pdf:unified

Access API at: http://localhost:8080/api Swagger UI at: http://localhost:8080/swagger-ui/index.html


Architecture

MODE=BOTH (Default)

┌─────────────────────────────────────┐
│     Port 8080 (External)            │
│  ┌───────────────────────────────┐  │
│  │         Nginx                 │  │
│  │  • Serves frontend (/)        │  │
│  │  • Proxies /api/* → backend   │  │
│  └───────────┬───────────────────┘  │
│              │                       │
│  ┌───────────▼───────────────────┐  │
│  │    Backend (Internal 8081)    │  │
│  │  • Spring Boot                │  │
│  │  • PDF Processing             │  │
│  │  • UnoServer                  │  │
│  └───────────────────────────────┘  │
└─────────────────────────────────────┘

MODE=FRONTEND

┌─────────────────────────────┐      ┌──────────────────┐
│   Frontend Container        │      │  Backend         │
│   Port 8080                 │      │  (External)      │
│  ┌───────────────────────┐  │      │                  │
│  │       Nginx           │  │──────▶  :8080/api       │
│  │  • Serves frontend    │  │      │                  │
│  │  • Proxies to backend │  │      │                  │
│  └───────────────────────┘  │      └──────────────────┘
└─────────────────────────────┘

MODE=BACKEND

┌─────────────────────────────┐
│   Backend Container         │
│   Port 8080                 │
│  ┌───────────────────────┐  │
│  │   Spring Boot         │  │
│  │  • API Endpoints      │  │
│  │  • PDF Processing     │  │
│  │  • UnoServer          │  │
│  └───────────────────────┘  │
└─────────────────────────────┘

Environment Variables

MODE Configuration

Variable Values Default Description
MODE BOTH, FRONTEND, BACKEND BOTH Container operation mode

MODE=BOTH Specific

Variable Default Description
BACKEND_INTERNAL_PORT 8081 Internal port for backend when MODE=BOTH

MODE=FRONTEND Specific

Variable Default Description
VITE_API_BASE_URL http://backend:8080 Backend URL for API proxying

Standard Configuration

All modes support standard Stirling-PDF environment variables:

  • DISABLE_ADDITIONAL_FEATURES - Enable/disable OCR and LibreOffice features
  • DOCKER_ENABLE_SECURITY - Enable authentication
  • PUID / PGID - User/Group IDs
  • SYSTEM_MAXFILESIZE - Max upload size (MB)
  • TESSERACT_LANGS - Comma-separated OCR language codes
  • JAVA_CUSTOM_OPTS - Additional JVM options

See full configuration docs at: https://docs.stirlingpdf.com


Docker Compose Examples

Example 1: All-in-One (MODE=BOTH)

File: docker/compose/docker-compose-unified-both.yml

services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:unified
    ports:
      - "8080:8080"
    volumes:
      - ./data:/usr/share/tessdata:rw
      - ./config:/configs:rw
    environment:
      MODE: BOTH
    restart: unless-stopped

Example 2: Separate Frontend & Backend

File: docker/compose/docker-compose-unified-frontend.yml

services:
  backend:
    image: stirlingtools/stirling-pdf:unified
    ports:
      - "8081:8080"
    environment:
      MODE: BACKEND
    volumes:
      - ./data:/usr/share/tessdata:rw
      - ./config:/configs:rw

  frontend:
    image: stirlingtools/stirling-pdf:unified
    ports:
      - "8080:8080"
    environment:
      MODE: FRONTEND
      VITE_API_BASE_URL: http://backend:8080
    depends_on:
      - backend

Example 3: Backend API Only

File: docker/compose/docker-compose-unified-backend.yml

services:
  stirling-pdf-api:
    image: stirlingtools/stirling-pdf:unified
    ports:
      - "8080:8080"
    environment:
      MODE: BACKEND
    volumes:
      - ./data:/usr/share/tessdata:rw
      - ./config:/configs:rw
    restart: unless-stopped

Building the Image

# From repository root
docker build -t stirlingtools/stirling-pdf:unified -f docker/Dockerfile.unified .

Build Arguments

Argument Description
VERSION_TAG Version tag for the image

Example:

docker build \
  --build-arg VERSION_TAG=v1.0.0 \
  -t stirlingtools/stirling-pdf:unified \
  -f docker/Dockerfile.unified .

Use Cases

1. Simple Deployment (MODE=BOTH)

  • Best for: Personal use, small teams, simple deployments
  • Pros: Single container, easy setup, minimal configuration
  • Cons: Frontend and backend scale together

2. Scaled Frontend (MODE=FRONTEND + BACKEND)

  • Best for: High traffic, need to scale frontend independently
  • Pros: Scale frontend containers separately, CDN-friendly
  • Example:
    services:
      backend:
        image: stirlingtools/stirling-pdf:unified
        environment:
          MODE: BACKEND
        deploy:
          replicas: 1
    
      frontend:
        image: stirlingtools/stirling-pdf:unified
        environment:
          MODE: FRONTEND
          VITE_API_BASE_URL: http://backend:8080
        deploy:
          replicas: 5  # Scale frontend independently
    

3. API-Only (MODE=BACKEND)

  • Best for: Headless deployments, custom frontends, API integrations
  • Pros: Minimal resources, no nginx overhead
  • Example: Use with external frontend or API consumers

4. Multi-Backend Setup

  • Best for: Load balancing, high availability
  • Example:
    services:
      backend-1:
        image: stirlingtools/stirling-pdf:unified
        environment:
          MODE: BACKEND
    
      backend-2:
        image: stirlingtools/stirling-pdf:unified
        environment:
          MODE: BACKEND
    
      frontend:
        image: stirlingtools/stirling-pdf:unified
        environment:
          MODE: FRONTEND
          VITE_API_BASE_URL: http://load-balancer:8080
    

Port Configuration

All modes use port 8080 by default:

  • MODE=BOTH: Nginx listens on 8080, proxies to backend on internal 8081
  • MODE=FRONTEND: Nginx listens on 8080
  • MODE=BACKEND: Spring Boot listens on 8080

Expose port 8080 in all configurations:

ports:
  - "8080:8080"

Health Checks

MODE=BOTH and MODE=BACKEND

healthcheck:
  test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status || exit 1"]
  interval: 30s
  timeout: 10s
  retries: 3

MODE=FRONTEND

healthcheck:
  test: ["CMD-SHELL", "curl -f http://localhost:8080/ || exit 1"]
  interval: 30s
  timeout: 10s
  retries: 3

Troubleshooting

Check logs

docker logs stirling-pdf-container

Look for the startup banner:

===================================
Stirling-PDF Unified Container
MODE: BOTH
===================================

Invalid MODE error

ERROR: Invalid MODE 'XYZ'. Must be BOTH, FRONTEND, or BACKEND

Fix: Set MODE to one of the three valid values.

Frontend can't connect to backend (MODE=FRONTEND)

Check:

  1. VITE_API_BASE_URL points to correct backend URL
  2. Backend container is running and accessible
  3. Network connectivity between containers

Backend not starting (MODE=BOTH or BACKEND)

Check:

  1. Sufficient memory allocated (4GB recommended)
  2. Java heap size (JAVA_CUSTOM_OPTS)
  3. Volume permissions for /tmp/stirling-pdf

Migration Guide

From Separate Containers → MODE=BOTH

Before:

services:
  frontend:
    image: stirlingtools/stirling-pdf:frontend
    ports: ["80:80"]

  backend:
    image: stirlingtools/stirling-pdf:backend
    ports: ["8080:8080"]

After:

services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:unified
    ports: ["8080:8080"]
    environment:
      MODE: BOTH

From Legacy → MODE=BACKEND

services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:latest
    ports: ["8080:8080"]

Becomes:

services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:unified
    ports: ["8080:8080"]
    environment:
      MODE: BACKEND

Performance Tuning

MODE=BOTH

environment:
  JAVA_CUSTOM_OPTS: "-Xmx4g -XX:MaxRAMPercentage=75"
  BACKEND_INTERNAL_PORT: 8081
deploy:
  resources:
    limits:
      memory: 4G
    reservations:
      memory: 2G

MODE=FRONTEND (Lightweight)

deploy:
  resources:
    limits:
      memory: 512M
    reservations:
      memory: 256M

MODE=BACKEND (Heavy Processing)

environment:
  JAVA_CUSTOM_OPTS: "-Xmx8g"
deploy:
  resources:
    limits:
      memory: 10G
    reservations:
      memory: 4G

Security Considerations

  1. MODE=BOTH: Backend not exposed externally (runs on internal port)
  2. MODE=BACKEND: API exposed directly - consider API authentication
  3. MODE=FRONTEND: Only serves static files - minimal attack surface

Enable security features:

environment:
  DOCKER_ENABLE_SECURITY: "true"
  SECURITY_ENABLELOGIN: "true"

Support


License

MIT License - See repository for full details