docker/embedded/compose/README-remote-uno.md
This docker-compose configuration demonstrates running Stirling-PDF with separate UNO server containers for LibreOffice document conversion, enabling horizontal scaling and better resource isolation.
┌─────────────────────┐
│ Stirling-PDF │
│ (Main App) │
│ │
│ Uses BlockingQueue │
│ pool to distribute │
│ load across servers │
└──────┬──────┬───────┘
│ │
│ │ Remote endpoints
│ │ (hostLocation: remote)
│ │
┌───▼──┐ ┌─▼────┐
│ UNO │ │ UNO │
│ #1 │ │ #2 │
│:2002 │ │:2002 │
└──────┘ └──────┘
unoping health checkPROCESS_EXECUTOR_AUTO_UNO_SERVER: "false" # Disable local servers
# Define remote endpoints (Spring Boot list syntax)
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST: "unoserver1"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_PORT: "2002"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_HOST_LOCATION: "remote" # Critical!
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_0_PROTOCOL: "http"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST: "unoserver2"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_PORT: "2002"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_HOST_LOCATION: "remote"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_1_PROTOCOL: "http"
PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT: "2"
Should match endpoint count for optimal concurrency.
docker compose -f docker-compose-latest-security-remote-uno.yml up -d
# Watch all services
docker compose -f docker-compose-latest-security-remote-uno.yml logs -f
# Watch just UNO servers
docker compose -f docker-compose-latest-security-remote-uno.yml logs -f unoserver1 unoserver2
# Watch main app
docker compose -f docker-compose-latest-security-remote-uno.yml logs -f stirling-pdf
docker compose -f docker-compose-latest-security-remote-uno.yml ps
Should show all services healthy:
NAME STATUS
Stirling-PDF-Security-Remote-UNO Up (healthy)
UNO-Server-1 Up (healthy)
UNO-Server-2 Up (healthy)
Upload multiple documents for conversion and watch the logs - you'll see requests distributed across both UNO servers via the BlockingQueue pool.
To add a 3rd UNO server:
unoserver3:
container_name: UNO-Server-3
image: ghcr.io/unoconv/unoserver-docker:0.4.4
# ... same config as unoserver1/2
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST: "unoserver3"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_PORT: "2002"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_HOST_LOCATION: "remote"
PROCESS_EXECUTOR_UNO_SERVER_ENDPOINTS_2_PROTOCOL: "http"
PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT: "3" # Update!
depends_on: depends_on:
unoserver1:
condition: service_healthy
unoserver2:
condition: service_healthy
unoserver3:
condition: service_healthy
docker compose -f docker-compose-latest-security-remote-uno.yml up -d --scale unoserver1=3
Note: This requires removing container_name and hardcoded ports.
hostLocation: "auto" or missingHOSTLOCATION: "remote" for all endpointsPROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT to match endpoint countdocker compose logs unoserver1docker compose down -v (removes volumes)PROCESS_EXECUTOR_AUTO_UNO_SERVER: "true"
PROCESS_EXECUTOR_SESSION_LIMIT_LIBRE_OFFICE_SESSION_LIMIT: "2"
# Creates 2 servers on 127.0.0.1:2003, 127.0.0.1:2005 inside container (Stirling-PDF's own servers)
PROCESS_EXECUTOR_AUTO_UNO_SERVER: "false"
# Define external endpoints with hostLocation: "remote"
If your UNO servers use HTTPS (e.g., behind a reverse proxy):
PROCESS_EXECUTOR_UNOSERVERENDPOINTS_0_PROTOCOL: "https"
unoserver1:
healthcheck:
interval: 5s # Check more frequently
timeout: 3s
retries: 10
start_period: 60s # Give more startup time
To see detailed endpoint selection logs:
environment:
LOGGING_LEVEL_STIRLING_SOFTWARE_COMMON_UTIL_PROCESSEXECUTOR: DEBUG
This configuration showcases all the improvements from the PR reviews:
hostLocation: "remote")With 2 UNO servers, you can expect:
Tested with 100GB+ PDFs - BlockingQueue ensures no endpoint starvation.