Artificial Intelligence (AI) AWS

Docling Serve Document Conversion API on AWS User Guide

| Product: Docling Serve Document Conversion API AMI by cloudimg

Overview

Docling Serve is the HTTP API service around Docling, an open source toolkit that converts documents into clean, structured content. Point it at a PDF, DOCX, PPTX, HTML or image file and it returns well structured Markdown or JSON in which headings, paragraphs, lists and tables survive the conversion, using machine learning models that understand page layout and reconstruct table structure. Applications POST a document and receive content ready to index, chunk for retrieval augmented generation, feed to a language model, or store. Docling and Docling Serve are Linux Foundation AI & Data projects, originally created at IBM Research, and are released under the MIT licence.

The cloudimg AMI installs Docling Serve into a Python virtual environment at /opt/docling, runs it under uvicorn as an unprivileged docling system account bound to loopback, fronts it with a single nginx gateway on TCP 80 that enforces HTTP Basic authentication on every path, and generates a unique API password on the first boot of every instance. The layout, table structure and OCR models are baked into the image and the service runs in offline mode, so both text based and scanned documents convert without the instance ever reaching out to the internet. Backed by 24/7 cloudimg support.

What is included:

  • docling-serve 1.27.0 and the docling conversion engine (docling-slim 2.114.0), both MIT licensed
  • PyTorch 2.13 (CPU build) — no GPU is required anywhere
  • Baked ML models, all licences verified against the artifacts at build time: document layout analysis (docling-layout-heron, Apache-2.0), table structure / TableFormer (docling-models, CDLA-Permissive-2.0), and OCR (RapidOCR PP-OCR, Apache-2.0)
  • nginx as an authenticating reverse proxy, the only network reachable surface
  • A built in UI playground at /ui, an interactive Swagger UI at /swagger and a ReDoc reference at /docs
  • A per instance API password generated on first boot into a root only file
  • An unauthenticated /healthz endpoint for load balancer probes

The Docling Serve conversion playground served behind the per instance credential, with format, pipeline and OCR options for converting a document interactively in the browser

Key facts

Item Value
Install root /opt/docling
Baked models /opt/docling/models
Credentials file /root/docling-credentials.txt
API user admin
Backend (loopback) 127.0.0.1:5001
Public API TCP 80 via nginx
UI playground /ui
Swagger UI /swagger
ReDoc API reference /docs
Recommended instance type m5.large (2 vCPU / 8 GiB)

Connecting to your instance

An AWS Marketplace listing can offer the same product on several operating systems; each OS variant has its own default SSH login user. Connect as the user for the variant you launched:

OS variant Default SSH user
Ubuntu 24.04 ubuntu
ssh <ssh-user>@<public-ip>

Prerequisites

  • An AWS account and either the AWS Management Console or the AWS CLI.
  • An EC2 key pair for SSH access.
  • A security group that allows inbound TCP 22 (SSH) and TCP 80 (the API) from the addresses you will connect from. Restrict both to your own IP ranges.
  • The recommended instance type is m5.large (2 vCPU / 8 GiB). The models load to roughly 2.7 GiB resident; the appliance runs on a 4 GiB instance for evaluation, but m5.large gives headroom for larger documents and concurrent requests. No GPU is needed.

Step 1 — Launch from AWS Marketplace

  1. In the AWS Marketplace console, find Docling Serve Document Conversion API AMI by cloudimg and choose Continue to Subscribe, then Continue to Configuration and Continue to Launch.
  2. Choose the software version and your region.
  3. Select the instance type (m5.large recommended), your VPC and subnet, and a security group that allows inbound TCP 22 and TCP 80 from your own IP ranges only.
  4. Select your EC2 key pair and launch.
  5. When the instance is running, note its public IP address (or DNS name).

Step 2 — Launch from the AWS CLI

Replace the AMI id with the one shown on the Marketplace listing for your region, and use your own key pair and security group.

aws ec2 run-instances \
  --image-id ami-xxxxxxxxxxxxxxxxx \
  --instance-type m5.large \
  --key-name my-key \
  --security-group-ids sg-xxxxxxxx \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=docling-serve}]'

Make sure the security group allows inbound TCP 22 and TCP 80 from your own IP ranges only.

Step 3 — Connect to your instance

ssh ubuntu@<public-ip>

The login banner shows where to find the credentials file, the model provenance and this guide. Use the SSH user for your OS variant from the table above.

Step 4 — Confirm the service is running

systemctl is-active docling-serve.service nginx.service

Expected output:

active
active

The uvicorn backend listens on loopback only and nginx is the single authenticated front end. Confirm the bind and the unauthenticated health probe:

sudo ss -tln | grep -E ':5001|:80 '
curl -s http://127.0.0.1/healthz

Expected output:

LISTEN 0      511          0.0.0.0:80        0.0.0.0:*
LISTEN 0      2048       127.0.0.1:5001      0.0.0.0:*
ok

The backend on 127.0.0.1:5001 is not reachable from outside the instance; every request arrives through nginx on port 80.

Step 5 — Retrieve your API password

Every instance generates its own password on first boot. There is no default login and no shared secret between deployments.

sudo cat /root/docling-credentials.txt

The file is readable only by root (0600) and contains DOCLING_URL, DOCLING_USERNAME and DOCLING_PASSWORD. Store the password in your secret manager and treat it as you would any API key. In the commands below, replace <DOCLING_PASSWORD> with this value.

Step 6 — Confirm authentication is enforced

Every API path requires the credential. An unauthenticated conversion request is refused:

curl -s -o /dev/null -w 'no credential -> HTTP %{http_code}\n' \
  -X POST http://127.0.0.1/v1/convert/file \
  -F 'files=@/opt/docling/samples/sample.pdf;type=application/pdf' \
  -F do_ocr=false -F to_formats=md

Expected output:

no credential -> HTTP 401

With the per instance password the same request succeeds:

curl -s -o /dev/null -w 'per instance password -> HTTP %{http_code}\n' \
  -u admin:<DOCLING_PASSWORD> \
  -X POST http://127.0.0.1/v1/convert/file \
  -F 'files=@/opt/docling/samples/sample.pdf;type=application/pdf' \
  -F do_ocr=false -F to_formats=md

Expected output:

per instance password -> HTTP 200

A wrong password is refused with 401 as well, so the credential is genuinely enforced rather than decorative.

Step 7 — Convert a document to Markdown

The image ships a small synthetic sample document at /opt/docling/samples/sample.pdf — a text layer PDF with a heading, a paragraph and a table. Convert it and extract the Markdown from the response. Passing do_ocr=false uses the fast, fully offline text extraction path together with the layout and table models.

curl -s -u admin:<DOCLING_PASSWORD> \
  -X POST http://127.0.0.1/v1/convert/file \
  -F 'files=@/opt/docling/samples/sample.pdf;type=application/pdf' \
  -F do_ocr=false -F to_formats=md \
  | python3 -c 'import sys,json; print(json.load(sys.stdin)["document"]["md_content"])'

Expected output:

## CLOUDIMG DOCLING SAMPLE INVOICE

This is a synthetic sample document authored by cloudimg to verify document conversion end to end. Verification marker: DOCLINGPROOF7Q2X.

## Line items

| Item          |   Quantity |   Unit Price |
|---------------|------------|--------------|
| Widget Alpha  |          3 |        12.00 |
| Sprocket Beta |          5 |         4.50 |
| Cog Gamma     |          2 |         9.75 |

The headings became Markdown headings and the table became a Markdown table — the layout model located the page elements and the TableFormer model reconstructed the table grid. To convert your own document, replace the file path. PDF, DOCX, PPTX, HTML, Markdown, AsciiDoc, CSV and common image formats are accepted.

The response is a JSON object with a document field. Besides md_content it also carries json_content, html_content, text_content and doctags_content, so you can ask for whichever representation suits your pipeline via to_formats (for example -F to_formats=json).

Step 8 — Run OCR on a scanned image (fully offline)

Scanned or image only documents have no text layer, so they need optical character recognition. The RapidOCR models are baked into the image, so OCR runs entirely offline — nothing is sent to any external service. The image ships a synthetic scanned sample at /opt/docling/samples/ocr_sample.png. Convert it with do_ocr=true:

curl -s -u admin:<DOCLING_PASSWORD> \
  -X POST http://127.0.0.1/v1/convert/file \
  -F 'files=@/opt/docling/samples/ocr_sample.png;type=image/png' \
  -F do_ocr=true -F force_ocr=true -F to_formats=md \
  | python3 -c 'import sys,json; print(json.load(sys.stdin)["document"]["md_content"])'

Expected output:

## OCRPROOF ZEBRA 4831

synthetic scanned image, no text layer

The recognised text is returned as Markdown. To convert your own scanned document, replace the file path. OCR is more CPU intensive than text extraction, so scanned documents take longer than text layer PDFs of the same length.

Step 9 — Use the built in UI playground and API docs

The image enables the Docling Serve playground at /ui, an interactive Swagger UI at /swagger and a ReDoc reference at /docs. All three are behind the same Basic authentication, so your browser prompts once for the admin credential. In a browser, go to http://<public-ip>/ui and sign in.

Upload a document on the Convert File tab and convert it to see the structured output rendered directly in the page. Below, the sample PDF has been converted and the Markdown tab shows the reconstructed heading, the verification marker and the table.

The playground after converting the sample PDF, with the result tabs showing the reconstructed Markdown containing the document heading, the verification marker and the table rendered in the browser

The /docs page is the ReDoc API reference for the stable v1 API, grouping the health, convert, chunk, tasks, clear and management endpoints.

The Docling Serve ReDoc API reference at /docs listing the health, convert, chunk, tasks, clear and management endpoint groups

The POST /v1/convert/file operation expanded in the API reference, showing the multipart file upload, the target and format parameters and the accepted input formats

Step 10 — Call the API from your application

Any HTTP client works. This Python example converts a local PDF and prints the Markdown:

import requests

with open("report.pdf", "rb") as fh:
    resp = requests.post(
        "http://<public-ip>/v1/convert/file",
        auth=("admin", "<DOCLING_PASSWORD>"),
        files={"files": ("report.pdf", fh, "application/pdf")},
        data={"do_ocr": "false", "to_formats": "md"},
        timeout=600,
    )
resp.raise_for_status()
print(resp.json()["document"]["md_content"])

For very large documents or batch workloads, Docling Serve also exposes asynchronous conversion endpoints under /v1/convert/source/async with task polling; see /docs for the full contract.

The models and their licences

Document conversion is driven by machine learning models, and each model is a separately licensed artifact. This image bakes only models that permit commercial use and redistribution, and every licence was verified at build time against the shipped model card rather than a documentation badge. The exact models, their sizes and sha256 checksums are recorded on the image:

cat /opt/docling/MODEL-PROVENANCE.txt
Model Purpose Licence
docling-layout-heron Document layout analysis (RT-DETRv2) Apache-2.0
docling-models TableFormer Table structure reconstruction CDLA-Permissive-2.0
RapidOCR PP-OCR Optical character recognition Apache-2.0

None of the shipped models is research only or non commercial, and none is fine tuned from a restricted base. EasyOCR is deliberately not used because its text detector lineage is less clear cut; RapidOCR's PaddleOCR derived models are Apache-2.0 and are the OCR stack shipped. The service runs with HF_HUB_OFFLINE=1, so it always loads these baked models and never reaches out to download anything during a conversion.

Document handling and log hygiene

Documents you submit are the sensitive artifact for this product, so the image is configured to keep them off disk and out of the logs:

  • The nginx access log is disabled on every path, and nginx never logs request bodies.
  • The service runs at log level WARNING, so document filenames are not written to the system journal. Document content is never logged at any level.
  • The synchronous /v1/convert/file endpoint returns the result inline and does not persist the submitted document or its output on disk after the response.

You can confirm nothing you submit leaks into the logs by converting a document containing a known marker and then searching /var/log and the journal for it.

Server components

Component Role
docling-serve.service The uvicorn API server, bound to 127.0.0.1:5001, running as the docling user
nginx.service Authenticating reverse proxy on TCP 80, the only network reachable surface
docling-firstboot.service One shot unit that generates the per instance password on first boot and proves a real conversion round trip before marking the boot complete

Filesystem layout

Path Contents
/opt/docling/venv Python virtual environment with docling-serve and its dependencies
/opt/docling/models Baked layout, table structure and OCR models
/opt/docling/samples Synthetic sample documents used by the built in self test
/opt/docling/MODEL-PROVENANCE.txt The shipped models with sizes, sha256 and licences
/var/lib/docling Writable scratch and cache directory owned by the docling user
/root/docling-credentials.txt The per instance API password, root only
/etc/nginx/cloudimg-docling.htpasswd The nginx Basic auth password file

Managing the service

sudo systemctl restart docling-serve.service
sudo systemctl restart nginx.service
sudo journalctl -u docling-serve.service -n 50 --no-pager

Changing the API password

Set a new Basic auth password for the admin user and reload nginx:

sudo sh -c 'printf "admin:%s\n" "$(openssl passwd -apr1 NEW_PASSWORD)" > /etc/nginx/cloudimg-docling.htpasswd'
sudo systemctl reload nginx

Replace NEW_PASSWORD with your chosen password.

Terminating TLS

The image serves the API over HTTP on port 80. For production, terminate TLS in front of the service. Two common approaches:

  • AWS Application Load Balancer — put the instance in a target group, terminate TLS on the ALB with an AWS Certificate Manager certificate, and use the unauthenticated /healthz path as the target group health check.
  • Certbot on the instance — point a DNS name at the instance and obtain a certificate directly:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d docling.example.com

Certbot obtains a certificate, rewrites the nginx site to listen on 443 and sets up automatic renewal. Restrict inbound access to TCP 443 (and 22) in your security group once TLS is in place.

Troubleshooting

  • 401 Unauthorized — you did not supply the credential, or the password is wrong. Retrieve it with sudo cat /root/docling-credentials.txt and pass it as -u admin:PASSWORD.
  • The API does not respond — check systemctl is-active docling-serve.service nginx.service. The backend loads the models at startup, which takes a few seconds after a restart.
  • A conversion is slow — OCR (do_ocr=true) is CPU intensive. Use m5.large or larger for heavier workloads and concurrent requests.
  • Read the logssudo journalctl -u docling-serve.service -n 100 --no-pager.

Security recommendations

  • Keep TCP 80 (and 22) restricted to your own IP ranges in the security group.
  • Put the service behind TLS as shown above before using it in production.
  • Rotate the API password after first login and store it in a secret manager.
  • The uvicorn backend is bound to loopback; do not reconfigure it to bind 0.0.0.0, which would bypass the authenticating proxy.

On startup

On the first boot of every instance, docling-firstboot.service generates a unique 24 character API password, writes it to /root/docling-credentials.txt (root only), starts the service, and proves a real conversion round trip before marking the boot complete. No default credential is ever baked into the image. Subsequent boots reuse the generated password.

Support

Every cloudimg deployment is backed by 24/7 support. If you have questions about this image or need help with your deployment, contact the cloudimg support team at support@cloudimg.co.uk.