Reverse Proxy Configuration#
docling-serve has first-class support for running behind a reverse proxy. Three orthogonal knobs cover the most common deployment needs:
| Concern | Setting | Default |
|---|---|---|
Proxy header forwarding (X-Forwarded-*) | UVICORN_PROXY_HEADERS | true |
| Context-path / subpath prefix | UVICORN_ROOT_PATH | "" (empty) |
Gradio UI root_path | Derived from UVICORN_ROOT_PATH | /ui |
UVICORN_PROXY_HEADERS — X-Forwarded-* header trust#
UvicornSettings sets proxy_headers = True by default. This is forwarded directly to uvicorn.run(proxy_headers=...) at startup , instructing uvicorn to parse X-Forwarded-Proto, X-Forwarded-For, and X-Forwarded-Port and use them to populate request.client and request.url.scheme. The CLI --proxy-headers / --no-proxy-headers flag and the UVICORN_PROXY_HEADERS env var both control this setting .
Set UVICORN_PROXY_HEADERS=false only when docling-serve is not behind a trusted proxy, as enabling it on an internet-facing port can let clients spoof their IP address.
UVICORN_ROOT_PATH — context path / subpath prefix#
When docling-serve is mounted at a URL subpath (e.g., https://host/docling/), set:
UVICORN_ROOT_PATH=/docling
This is passed as root_path to uvicorn.run() , which in turn sets the ASGI root_path that FastAPI uses to generate correct OpenAPI spec URLs and redirect targets. The setting can also be supplied via the CLI --root-path flag on both docling-serve run and docling-serve dev .
This feature was introduced in PR #396 .
Gradio UI root_path — /ui under a subpath#
When the Gradio UI is enabled (DOCLING_SERVE_ENABLE_UI=true), create_app() automatically derives Gradio's root_path from uvicorn_settings.root_path :
gradio_root_path = (
f"{uvicorn_settings.root_path}/ui"
if uvicorn_settings.root_path
else "/ui"
)
app = gr.mount_gradio_app(app, gradio_ui, path="/ui", root_path=gradio_root_path)
So setting UVICORN_ROOT_PATH=/docling automatically configures Gradio with root_path=/docling/ui, ensuring Gradio's asset and API links use the correct subpath. No separate Gradio environment variable is needed.
Known limitation: non-standard ports and Gradio asset URLs#
When the reverse proxy listens on a non-standard port (e.g., 8443), some Gradio-generated URLs for static assets (JS/CSS) and heartbeat requests may omit the port. This is a Gradio-side limitation — docling-serve passes proxy_headers=True and a correct root_path to Gradio, but Gradio does not fully propagate X-Forwarded-Port into all its generated URLs .
Workarounds:
- Use a standard port (443 for HTTPS / 80 for HTTP) so the port is implicit.
- In nginx, use
$http_hostinstead of$hostfor theX-Forwarded-Hostheader. This has been confirmed to resolve the port-missing issue in practice . - Use
nginx sub_filterto rewrite non-standard ports in HTML/CSS/JS responses.
Quick-reference: key env vars#
| Variable | Description | Default |
|---|---|---|
UVICORN_PROXY_HEADERS | Trust X-Forwarded-* headers | true |
UVICORN_ROOT_PATH | ASGI root path / URL prefix | "" |
UVICORN_HOST | Bind address | 0.0.0.0 |
UVICORN_PORT | Bind port | 5001 |
All UVICORN_* variables are defined in UvicornSettings and applied in __main__.py.