How to Configure LibreOffice for Document-to-PDF Conversions in Stirling-PDF
Stirling-PDF converts office documents to PDF by executing a local LibreOffice binary configured via settings.yml, with configurable concurrency limits, timeouts, and optional unoconvert fallback.
Stirling-PDF provides REST endpoints to transform DOCX, PPTX, ODT, and other office formats into PDF through LibreOffice command-line automation. The application manages conversion queues, temporary profiles, and process timeouts through YAML configuration properties. Understanding how to configure LibreOffice for document-to-PDF conversions ensures stable performance in both Docker and bare-metal deployments.
Conversion Architecture and Flow
The conversion pipeline begins in ConvertOfficeController.java, which handles multipart file uploads at the /api/v1/convert/office/file/pdf endpoint. When a document arrives, the controller creates a temporary work directory using Files.createTempDirectory("office2pdf_") to isolate the conversion process.
The controller selects the conversion command by checking RuntimePathConfig.getUnoConvertPath() first. If unoconvert is enabled and available, it uses that binary; otherwise, it falls back to the LibreOffice soffice command retrieved from RuntimePathConfig.getSOfficePath(). According to the source in RuntimePathConfig.java#L94-L98, the default path inside Docker containers is /usr/bin/soffice, while host installations expect the binary on the system PATH.
Execution flows through ProcessExecutor, which enforces the LibreOffice session limit (processExecutor.sessionLimit.libreOfficeSessionLimit) and timeout (processExecutor.timeoutMinutes.libreOfficeTimeoutMinutes). After conversion, the controller cleans up the transient LibreOffice profile directory created via Files.createTempDirectory("libreoffice_profile_").
Configuring the LibreOffice Binary Path
Specify the absolute path to the LibreOffice executable in settings.yml using the customPaths.operations.soffice property. This maps to ApplicationProperties.CustomPaths.Operations.soffice in the source.
customPaths:
operations:
soffice: /usr/bin/soffice
If omitted, Stirling-PDF searches for soffice on the system PATH. For Docker deployments, the default resolves to /usr/bin/soffice automatically.
Managing Concurrency and Resource Limits
Control parallel conversion capacity through session limits. The default libreOfficeSessionLimit is 1, meaning only one conversion runs at a time. Increase this value in settings.yml to process multiple documents concurrently.
processExecutor:
sessionLimit:
libreOfficeSessionLimit: 3
This property corresponds to ProcessExecutor.SessionLimit.getLibreOfficeSessionLimit() defined in ApplicationProperties.java.
Prevent hung processes by setting the libreOfficeTimeoutMinutes value. The default timeout is 30 minutes, after which ProcessExecutor aborts the conversion.
processExecutor:
timeoutMinutes:
libreOfficeTimeoutMinutes: 15
Note the exact property name in ApplicationProperties.java references getLibreOfficeTimeoutMinutes() (camelCase with capital 'O' in Office).
Temporary Profile and Unoconvert Configuration
LibreOffice requires a user profile directory for each conversion. By default, Stirling-PDF creates a temporary folder under the system temp directory using the prefix libreoffice_profile_. To specify a persistent location—useful for debugging or restricted environments—set tempFileManagement.libreofficeDir:
tempFileManagement:
libreofficeDir: /var/tmp/libreoffice-profile
This maps to ApplicationProperties.TempFileManagement.getLibreofficeDir().
To use unoconvert as a lightweight alternative, enable it by setting both the binary path and the group configuration:
customPaths:
operations:
unoconvert: /usr/local/bin/unoconvert
endpointConfiguration:
groups:
unoconvert:
enabled: true
When enabled, ConvertOfficeController attempts unoconvert first before falling back to the standard LibreOffice binary.
Optional LibreOffice Listener for High-Volume Scenarios
For Docker environments processing frequent conversions, LibreOfficeListener.java maintains a headless LibreOffice process alive between requests. This eliminates the startup overhead for each conversion. The listener automatically terminates after 20 minutes of inactivity (defined by ACTIVITY_TIMEOUT).
While the listener starts automatically when referenced, you can verify its status through logs indicating the process is ready to accept connections on the socket.
Complete Configuration Example
Combine these settings into a single settings.yml file:
customPaths:
operations:
soffice: /usr/bin/soffice
unoconvert: /usr/local/bin/unoconvert
endpointConfiguration:
groups:
unoconvert:
enabled: true
processExecutor:
sessionLimit:
libreOfficeSessionLimit: 2
timeoutMinutes:
libreOfficeTimeoutMinutes: 10
tempFileManagement:
libreofficeDir: /opt/stirling/libreoffice-temp
Invoking the Conversion API
Submit documents to the conversion endpoint using standard HTTP multipart requests:
curl -X POST "http://localhost:8080/api/v1/convert/office/file/pdf" \
-F "file=@document.docx" \
-o document_convertedToPDF.pdf
The processFileToPDF method in ConvertOfficeController.java appends _convertedToPDF.pdf to the original filename in the response.
Summary
- Binary Location: Set
customPaths.operations.sofficeto the absolute path ofsofficeor rely on Docker defaults at/usr/bin/soffice. - Concurrency: Control parallel processing with
processExecutor.sessionLimit.libreOfficeSessionLimit(default 1). - Timeouts: Prevent process hangs using
processExecutor.timeoutMinutes.libreOfficeTimeoutMinutes(default 30 minutes). - Temp Storage: Optionally pin LibreOffice profiles to a specific directory via
tempFileManagement.libreofficeDir. - Alternative Engine: Enable
unoconvertfor faster initialization by setting its path and enabling the group inendpointConfiguration.groups.unoconvert.enabled. - Key Classes: Configuration is loaded by
RuntimePathConfig, executed byProcessExecutor, and orchestrated byConvertOfficeController.
Frequently Asked Questions
Where does Stirling-PDF expect the LibreOffice executable to be installed?
By default, Stirling-PDF expects the soffice binary on the system PATH for standard installations. Inside Docker containers, the code in RuntimePathConfig.java automatically defaults to /usr/bin/soffice. You can override either default by setting customPaths.operations.soffice in settings.yml to the absolute binary path.
How can I prevent LibreOffice conversions from hanging indefinitely?
Set the processExecutor.timeoutMinutes.libreOfficeTimeoutMinutes property in settings.yml to a reasonable value such as 10 or 15 minutes. The ProcessExecutor class monitors execution time and terminates any conversion exceeding this limit, preventing resource exhaustion from frozen processes.
What is the difference between using LibreOffice and unoconvert in Stirling-PDF?
LibreOffice (soffice) is the full-featured office suite used for complex document rendering, while unoconvert is a lightweight wrapper that communicates with a running LibreOffice listener. Unoconvert typically offers faster conversion for simple documents because it avoids spawning a new process each time. Configure unoconvert by setting customPaths.operations.unoconvert and enabling endpointConfiguration.groups.unoconvert.enabled in your configuration.
Why is my LibreOffice conversion failing with permission errors in Docker?
This usually occurs when the temporary profile directory lacks write permissions. By default, Stirling-PDF creates a random temp folder, but you can specify a writable location using tempFileManagement.libreofficeDir in settings.yml. Ensure the directory is writable by the container user (typically UID 1000) and mounted as a volume if persistence is required between restarts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →