Open WebUI
Open WebUI supports pluggable content extraction backends. Xberg implements two of those backend APIs — the docling-serve endpoint and the external document loader endpoint, so it works as a drop-in replacement without patching Open WebUI.
How it works
Section titled “How it works”- A user uploads a document (PDF, DOCX, image, etc.) in Open WebUI.
- Open WebUI sends the file to Xberg’s API endpoint.
- Xberg extracts the content — running OCR where needed and returns Markdown.
- Open WebUI stores the Markdown in its vector database for retrieval-augmented generation.
Xberg supports 101 file formats and requires no GPU.
Prerequisites
Section titled “Prerequisites”- Docker and Docker Compose (v2)
- Open WebUI running or ready to deploy
- No GPU required — Xberg runs entirely on CPU
Setup with Docker Compose
Section titled “Setup with Docker Compose”This is the fastest way to get both services running together.
services: xberg: image: ghcr.io/xberg-io/xberg:latest-core ports: - "8000:8000" command: ["serve", "--host", "0.0.0.0", "--port", "8000"] volumes: - xberg-cache:/app/.xberg healthcheck: test: ["CMD", "xberg", "version"] interval: 10s timeout: 5s retries: 5
open-webui: image: ghcr.io/open-webui/open-webui:main ports: - "3000:8080" environment: CONTENT_EXTRACTION_ENGINE: "docling" DOCLING_SERVER_URL: "http://xberg:8000" depends_on: xberg: condition: service_healthy
volumes: xberg-cache:Start both services in detached mode:
docker compose up -dOpen http://localhost:3000, create an account, and upload a document. The extracted text will appear in the chat context.
docker run -d \ --name xberg \ -p 8000:8000 \ -v xberg-cache:/app/.xberg \ ghcr.io/xberg-io/xberg:latest-core \ serve --host 0.0.0.0 --port 8000xberg serve --host 0.0.0.0 --port 8000Then configure Open WebUI using one of the two engine modes below.
Choosing an engine mode
Section titled “Choosing an engine mode”Xberg exposes two Open WebUI–compatible APIs. Both return the same extracted content. So pick whichever fits your setup.
| Docling (recommended) | External | |
|---|---|---|
| Endpoint | POST /v1/convert/file |
PUT /process |
| Engine setting | docling |
external |
| URL variable | DOCLING_SERVER_URL |
EXTERNAL_DOCUMENT_LOADER_URL |
Set these environment variables on the Open WebUI container:
environment: CONTENT_EXTRACTION_ENGINE: "docling" DOCLING_SERVER_URL: "http://xberg:8000"Or via the Admin UI: Settings → Documents → Content Extraction Engine → select Docling → set server URL to http://xberg:8000.
Set these environment variables on the Open WebUI container:
environment: CONTENT_EXTRACTION_ENGINE: "external" EXTERNAL_DOCUMENT_LOADER_URL: "http://xberg:8000"Or via the Admin UI: Settings → Documents → Content Extraction Engine → select External → set URL to http://xberg:8000.
Verify it works
Section titled “Verify it works”Test the endpoints directly before debugging through Open WebUI.
curl -s -F "files=@invoice.pdf" http://localhost:8000/v1/convert/file | jq .{ "document": { "md_content": "# Invoice\n\nDate: 2026-01-15\n..." }, "status": "success"}curl -s -X PUT \ -H "Content-Type: application/pdf" \ -H "X-Filename: invoice.pdf" \ --data-binary @invoice.pdf \ http://localhost:8000/process | jq .{ "page_content": "# Invoice\n\nDate: 2026-01-15\n...", "metadata": { "source": "invoice.pdf" }}If the endpoint returns extracted text, the integration is working. Upload a document through Open WebUI to confirm end-to-end.
Large or slow documents
Section titled “Large or slow documents”Both endpoints enforce extraction_timeout_secs (default 600 seconds / 10 minutes) and return HTTP 500 if a document doesn’t finish extracting in time. Documents that lean on slow paths — VLM-based OCR, large scanned PDFs — can exceed the default on constrained hardware. Raise the limit in xberg.toml next to the compose file (auto-discovered on serve startup):
extraction_timeout_secs = 1800TOML has no null literal, so a TOML config can only raise the limit, not disable it; use a YAML or JSON config with extraction_timeout_secs: null (YAML) or "extraction_timeout_secs": null (JSON) to turn enforcement off entirely. For the Docker Compose setup above, mount the file alongside the xberg-cache volume and pass --config /app/xberg.toml in command (or rely on auto-discovery if the file lives in the container’s working directory).
Next steps
Section titled “Next steps”- Docker deployment guide — image variants, volumes, security hardening
- API server reference — all endpoints and configuration options
- OCR guide — language packs, engine selection, tuning
- Format support — full list of supported file types