# How to Configure LibreOffice for Document-to-PDF Conversions in Stirling-PDF

> Configure LibreOffice for PDF conversions with Stirling-PDF. Learn to set up your settings.yml for optimal performance, concurrency, and timeouts.

- Repository: [Stirling Tools/Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Stirling-PDF converts office documents to PDF by executing a local LibreOffice binary configured via [`settings.yml`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/settings.yml) using the `customPaths.operations.soffice` property. This maps to `ApplicationProperties.CustomPaths.Operations.soffice` in the source.

```yaml
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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/settings.yml) to process multiple documents concurrently.

```yaml
processExecutor:
  sessionLimit:
    libreOfficeSessionLimit: 3

```

This property corresponds to `ProcessExecutor.SessionLimit.getLibreOfficeSessionLimit()` defined in [`ApplicationProperties.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/ApplicationProperties.java).

Prevent hung processes by setting the **libreOfficeTimeoutMinutes** value. The default timeout is **30 minutes**, after which `ProcessExecutor` aborts the conversion.

```yaml
processExecutor:
  timeoutMinutes:
    libreOfficeTimeoutMinutes: 15

```

Note the exact property name in [`ApplicationProperties.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`:

```yaml
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:

```yaml
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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/settings.yml) file:

```yaml
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:

```bash
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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/ConvertOfficeController.java) appends `_convertedToPDF.pdf` to the original filename in the response.

## Summary

- **Binary Location**: Set `customPaths.operations.soffice` to the absolute path of `soffice` or 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 `unoconvert` for faster initialization by setting its path and enabling the group in `endpointConfiguration.groups.unoconvert.enabled`.
- **Key Classes**: Configuration is loaded by `RuntimePathConfig`, executed by `ProcessExecutor`, and orchestrated by `ConvertOfficeController`.

## 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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/RuntimePathConfig.java) automatically defaults to `/usr/bin/soffice`. You can override either default by setting `customPaths.operations.soffice` in [`settings.yml`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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.