Office Documents and LibreOffice
LM-Kit One reads Word, Excel and PowerPoint documents (.docx, .xlsx, .pptx) on its own.
The LibreOffice engine extends that to almost every office format in circulation: the legacy
binary formats (.doc, .xls, .ppt), OpenDocument, RTF, Visio, Publisher, Apple iWork,
WordPerfect, Lotus and dozens more. Once it is installed, those files upload like any other
document, preview as page thumbnails, export to a PDF laid out page for page as their
application prints them, and are parsed, indexed and searched by every pipeline of the server.
The engine is optional, installs from the admin panel in one click, and runs entirely on the
machine.
1What the engine adds#
| Family | Formats |
|---|---|
| Text documents | doc, docm, dot, dotx, dotm, rtf, odt, ott, fodt, wpd, wps, wri, lwp, hwp, pages, abw, sxw and older StarOffice formats |
| Spreadsheets | xls, xlsm, xlsb, xlt, xltx, xltm, ods, ots, fods, csv, tsv, dbf, dif, slk, Lotus 1-2-3, Quattro Pro, numbers |
| Presentations | ppt, pptm, pps, ppsx, ppsm, pot, potx, potm, odp, otp, fodp, key |
| Drawings and publications | odg, otg, fodg, vsd, vsdx, vsdm, vdx, pub, cdr, cmx, wpg, cgm, dxf, emf, wmf |
The authoritative list is whatever the server advertises: GET /lmkit/v1/files/supported-extensions
returns it under office, and GET /lmkit/v1/document-thumbnail/supported-formats under
office too. Both lists are empty while no LibreOffice is installed, so a client never uploads
a format the server would then refuse to read.
Word, Excel and PowerPoint files keep their native reading for parsing and search: the engine gives them thumbnails and a faithful PDF, it never replaces how their text is read.
2Install it#
Open Settings > Engines. The LibreOffice card says in one line whether a runtime is available and where it comes from; when none is, Install opens a short guided install whose steps tick as they complete:
- Download. The official Document Foundation package for the server's operating system and processor (Windows, Linux, macOS; x64 and arm64), at a pinned release, checked against its published SHA-256 before anything is unpacked.
- Unpack. Into the server's
tools/folder. Nothing is installed on the host: no registry entry, no shortcut, no system package. - System libraries (Linux). LibreOffice uses the host's own graphics, printing and
security libraries (cairo, cups, nss, the X11 client libraries, even though nothing is ever
displayed), and a minimal server lacks some of them. The server fetches the missing ones from
the host's own package repositories (signature-checked by
aptwith the host's keys, so they match the host's release exactly) and keeps them for LibreOffice alone: the host is not changed, and none of its libraries is shadowed. - Verify. The runtime must start and answer a version probe before it becomes the active one, so a damaged download is discarded rather than used.
The install can be closed while it runs; the card shows its progress. It ends on Test, which converts a generated document and reads the PDF back. Remove deletes the managed copy and the libraries provided for it.
Where the libraries cannot be fetched (a distribution outside the Debian and Ubuntu family, or a host without access to its package repositories), the card says how many are missing, and Fix shows them with the one command that installs them system-wide; run it, then Check again.
The server resolves the runtime in this order, the first match wins:
| Source | When to use it |
|---|---|
| The Executable path under the card's Advanced settings | An install you manage yourself |
The LMKIT_LIBREOFFICE_PATH environment variable |
Containers and configuration as code |
| The managed copy | The one-click install above |
| A system install at its standard location | LibreOffice already installed on the host |
soffice on the system PATH |
Anything else |
An offline server cannot download the managed copy: install LibreOffice by any means available on the host and leave the path empty, or point the path at it.
3What you get#
- Thumbnails.
GET /lmkit/v1/document-thumbnail/{fileId}renders any page of an office document, andGET /lmkit/v1/document-thumbnail/{fileId}/page-sizesreturns its page geometry. An OpenDocument file answers its first page from the preview image it carries when that image is large enough, before any conversion runs. - PDF export.
POST /lmkit/v1/document-to-pdflays the document out exactly as its application prints it. The response names the format insource_format(doc,xlsx,odp...) and what rendered it inrenderer(libreoffice). - Search and every document pipeline. Indexing, Markdown conversion, document parsing, extraction, chat with documents and redaction all accept the office formats directly. A spreadsheet is read as a workbook, so every cell is indexed in full; every other format is read from its PDF rendering, with its pages, tables and layout.
A document converts once: thumbnails page after page, its page sizes, its PDF and a re-index of the same file all reuse the first conversion.
4Speed#
LibreOffice takes seconds to start, so the server keeps a few instances running between documents (the workers) and hands each conversion to one that is already warm. A typical document then converts in a fraction of a second. Workers start on demand, the busiest periods start more of them up to the configured count, and idle ones stop to return their memory, the most recently used one always staying warm. With Start a worker with the server on, the first document after a restart does not wait either.
5Settings#
Every setting lives under the LibreOffice card's Advanced settings and in the
LibreOffice section of the settings file. All apply immediately except Workers, which applies at the next restart.
| Setting | File key | Default | Meaning |
|---|---|---|---|
| Executable path | LibreOfficePath |
empty | Explicit runtime; empty resolves as in section 2 |
| Workers | LibreOffice:Workers |
0 |
Documents converted at the same time; 0 is a quarter of the logical processors, between 1 and 4 |
| Conversion timeout | LibreOffice:ConversionTimeoutSeconds |
120 |
Longest one document may take |
| Idle worker shutdown | LibreOffice:IdleWorkerMinutes |
5 |
Idle time before a spare worker stops; 0 keeps every worker |
| Restart worker after | LibreOffice:RecycleAfterConversions |
100 |
Documents a worker converts before it restarts fresh |
| Conversion cache | LibreOffice:CacheSizeMB |
2048 |
Disk budget of converted documents, least recently used first out |
| Conversion cache folder | LibreOffice:CacheDirectory |
empty | Where converted documents are kept; empty is libreoffice-work/pdf-cache in the tools folder |
| Start a worker with the server | LibreOffice:WarmOnStart |
true |
Warm one worker at startup |
Each worker is a full LibreOffice of a few hundred megabytes: size Workers to the memory the host can spare, not only to its processors.
The conversion cache
A document is converted once: the result is kept, keyed by the document's content, so its thumbnails, its PDF and a re-index of the same file all reuse it. Everything in the cache is derived and can be deleted at any time; a document converts again the next time it is asked for.
- Where. By default
tools/libreoffice-work/pdf-cachein the state directory. The LibreOffice card's Advanced settings state the folder in effect, with its size and file count beneath it. - How big. At most Conversion cache (MB); once full, the least recently used conversions are deleted first.
- Clear it. Clear cache under the same settings, or
POST /lmkit/v1/admin/libreoffice/cache/delete-all(GET .../libreoffice/cache/disk-usagereads its size). Deleting the folder's files by hand while the server runs is safe too. - Move it. Set Conversion cache folder (
LibreOffice:CacheDirectory) to another disk; a relative path resolves against the state directory. It applies to the next conversion without a restart, and the previous folder keeps its files until you clear or delete it. The folder belongs to one node: on a farm, each node keeps its own.
6Untrusted documents#
Office files are a classic attack surface, and every one the server reads is treated as untrusted:
- Each worker runs on a private profile, never the host user's, hardened before its first start: macros never run, embedded active content (OLE objects, DDE) is disabled, links from untrusted locations are blocked, and links to other files or to the network are never refreshed when a document loads.
- Documents are opened read-only, with macro execution and link updates refused by the load itself, and without any interactive prompt: a document asking a question fails instead of waiting.
- A conversion that runs past its timeout is stopped with its whole process tree, and its worker starts again from a clean profile.
7Errors#
| Code | Status | Meaning |
|---|---|---|
office_runtime_unavailable |
503 | No LibreOffice on this server: install it from Settings > Engines |
encrypted_document |
422 | The document is password-protected |
conversion_timeout |
504 | The document took longer than the conversion timeout |
conversion_failed |
422 | LibreOffice could not read the document; the message carries its reason |
8Containers and farms#
The engine is per node: each node resolves its own runtime, and the managed copy (with the
libraries provided for it) lives in that node's tools/ folder, next to the other
state. On a farm, install
it on every node that serves documents, or bake it into the image.
The official container image carries LibreOffice already: the release Settings > Engines would
install, pinned by version and checksum, under /opt, with every system library it links
against. Nothing is installed or fetched, the LibreOffice card reads it as the system copy, and
a new image brings the engine of its release (Containers). A copy
installed from Settings > Engines, or one named by LMKIT_LIBREOFFICE_PATH, still takes
precedence (section 3).
Fonts decide how faithfully a document lays out. The Document Foundation's build carries its own families (Liberation, Carlito, Caladea and DejaVu stand in for Arial, Times New Roman, Calibri and Cambria, metric for metric); a derived image adds the families your documents use, and CJK fonts when they contain Chinese, Japanese or Korean text:
FROM lmkitone/lm-kit-one:latest
RUN apt-get update \
&& apt-get install -y --no-install-recommends fonts-noto-cjk \
&& rm -rf /var/lib/apt/lists/*