Compare commits

...

5 commits

Author SHA1 Message Date
Pier-Jean Malandrino
c3d4b11f48 fix(ci): install pytestarch in docling-compat workflow
Some checks failed
CI / Backend tests (push) Has been cancelled
CI / Frontend tests & build (push) Has been cancelled
CI / E2E API tests (Karate) (push) Has been cancelled
CI / E2E UI tests (Karate UI) (push) Has been cancelled
The daily docling-compat job manually installed only pytest, pytest-asyncio
and httpx, which made test_architecture.py fail with ModuleNotFoundError:
no module named 'pytestarch' — wrongly opening 'Docling compatibility break'
issues. Align with ci.yml by installing requirements-test.txt instead.
2026-05-05 09:38:36 +02:00
Pier-Jean Malandrino
2807cc3aea fix(nginx): move template outside sites-enabled to avoid nginx loading it raw
Some checks failed
Release Docker Images / Build & push — local (push) Has been cancelled
Release Docker Images / Build & push — remote (push) Has been cancelled
2026-04-30 12:15:46 +02:00
Pier-Jean Malandrino
9f2c61839e chore(release): 0.5.1 2026-04-30 11:38:14 +02:00
Pier-Jean Malandrino
2e2c2eaa98 docs(readme): document NGINX_MAX_BODY_SIZE env var and nginx upload layer 2026-04-30 11:38:14 +02:00
Pier-Jean Malandrino
789b07c7d1 fix(nginx): make upload body size configurable via NGINX_MAX_BODY_SIZE env var
nginx.conf was hard-capped at 5M, causing 413 on uploads larger than 5MB
despite the backend accepting up to MAX_FILE_SIZE_MB (default 50).

Both nginx configs become envsubst templates. NGINX_MAX_BODY_SIZE defaults
to 200M so the backend application limit is always the effective arbiter.
gettext-base added to the single-image apt deps to provide envsubst.
2026-04-30 11:38:14 +02:00
9 changed files with 29 additions and 11 deletions

View file

@ -18,6 +18,10 @@
# Max upload file size in MB (default: 50, 0 = unlimited) # Max upload file size in MB (default: 50, 0 = unlimited)
# MAX_FILE_SIZE_MB=50 # MAX_FILE_SIZE_MB=50
# Nginx body size limit — nginx format (default: 200M, 0 = unlimited).
# Must be >= MAX_FILE_SIZE_MB. Backend MAX_FILE_SIZE_MB is the effective arbiter.
# NGINX_MAX_BODY_SIZE=200M
# Max pages per PDF (default: 0 = unlimited). Set to 20 for HF Spaces. # Max pages per PDF (default: 0 = unlimited). Set to 20 for HF Spaces.
# MAX_PAGE_COUNT=0 # MAX_PAGE_COUNT=0

View file

@ -27,7 +27,7 @@ jobs:
with: with:
python-version: "3.12" python-version: "3.12"
cache: pip cache: pip
cache-dependency-path: document-parser/requirements.txt cache-dependency-path: document-parser/requirements-test.txt
- name: Install system dependencies - name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends poppler-utils run: sudo apt-get update && sudo apt-get install -y --no-install-recommends poppler-utils
@ -35,8 +35,8 @@ jobs:
- name: Install pinned dependencies - name: Install pinned dependencies
run: | run: |
pip install --upgrade pip pip install --upgrade pip
pip install -r requirements.txt pip install -r requirements-test.txt
pip install pytest pytest-asyncio httpx pip install httpx
- name: Upgrade docling to latest - name: Upgrade docling to latest
id: versions id: versions

View file

@ -4,6 +4,12 @@ All notable changes to Docling Studio will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/). The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
## [0.5.1] - 2026-04-30
### Fixed
- Nginx upload body cap raised from 5 MB to 200 MB (`NGINX_MAX_BODY_SIZE`, default `200M`); uploads larger than 5 MB no longer returned 413 before reaching the backend.
## [0.5.0] - 2026-04-28 ## [0.5.0] - 2026-04-28
### Added ### Added

View file

@ -24,10 +24,11 @@ FROM python:3.12-slim AS base
ARG APP_VERSION=dev ARG APP_VERSION=dev
ENV APP_VERSION=${APP_VERSION} ENV APP_VERSION=${APP_VERSION}
# System deps: poppler (pdf2image), nginx # System deps: poppler (pdf2image), nginx, gettext-base (envsubst for nginx template)
RUN apt-get update && apt-get install -y --no-install-recommends \ RUN apt-get update && apt-get install -y --no-install-recommends \
poppler-utils \ poppler-utils \
nginx \ nginx \
gettext-base \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Python deps (common) # Python deps (common)
@ -41,8 +42,8 @@ COPY document-parser/ .
# Frontend static files # Frontend static files
COPY --from=frontend-build /build/dist /usr/share/nginx/html COPY --from=frontend-build /build/dist /usr/share/nginx/html
# Nginx config # Nginx config (template stored outside sites-enabled to avoid nginx loading it raw)
COPY nginx.conf /etc/nginx/sites-enabled/default COPY nginx.conf.template /etc/nginx/default.template
# Non-root user # Non-root user
RUN useradd --create-home --shell /bin/bash appuser RUN useradd --create-home --shell /bin/bash appuser
@ -52,10 +53,11 @@ RUN mkdir -p /app/uploads /app/data && chown -R appuser:appuser /app
ENV UPLOAD_DIR=/app/uploads ENV UPLOAD_DIR=/app/uploads
ENV DB_PATH=/app/data/docling_studio.db ENV DB_PATH=/app/data/docling_studio.db
ENV NGINX_MAX_BODY_SIZE=200M
EXPOSE 3000 EXPOSE 3000
CMD ["sh", "-c", "nginx && exec su appuser -c 'uvicorn main:app --host 127.0.0.1 --port 8000'"] CMD ["sh", "-c", "envsubst '${NGINX_MAX_BODY_SIZE}' < /etc/nginx/default.template > /etc/nginx/sites-enabled/default && nginx && exec su appuser -c 'uvicorn main:app --host 127.0.0.1 --port 8000'"]
# --- Remote: lightweight, delegates to Docling Serve --- # --- Remote: lightweight, delegates to Docling Serve ---
FROM base AS remote FROM base AS remote

View file

@ -210,6 +210,7 @@ All configuration is done via environment variables. See [`.env.example`](.env.e
| `BATCH_PAGE_SIZE` | `10` | Pages per batch (`0` = process all at once) | | `BATCH_PAGE_SIZE` | `10` | Pages per batch (`0` = process all at once) |
| `MAX_FILE_SIZE_MB` | `50` | Maximum upload file size in MB (`0` = unlimited) | | `MAX_FILE_SIZE_MB` | `50` | Maximum upload file size in MB (`0` = unlimited) |
| `MAX_PAGE_COUNT` | `0` | Maximum number of pages per document (`0` = unlimited) | | `MAX_PAGE_COUNT` | `0` | Maximum number of pages per document (`0` = unlimited) |
| `NGINX_MAX_BODY_SIZE` | `200M` | Nginx request body limit — nginx format (`200M`, `0` = unlimited). Must be ≥ `MAX_FILE_SIZE_MB`. |
| `RATE_LIMIT_RPM` | `100` | Max requests per minute per IP (`0` = disabled) | | `RATE_LIMIT_RPM` | `100` | Max requests per minute per IP (`0` = disabled) |
## Upload Limits ## Upload Limits
@ -218,8 +219,9 @@ Docling Studio enforces configurable limits on uploaded documents to protect the
- **`MAX_FILE_SIZE_MB`** (default `50`) — rejects uploads exceeding this size. Validated at two levels: early `Content-Length` check and streaming byte count. - **`MAX_FILE_SIZE_MB`** (default `50`) — rejects uploads exceeding this size. Validated at two levels: early `Content-Length` check and streaming byte count.
- **`MAX_PAGE_COUNT`** (default `0` = unlimited) — rejects documents with more pages than allowed. Useful on shared instances or Hugging Face Spaces to cap processing time. - **`MAX_PAGE_COUNT`** (default `0` = unlimited) — rejects documents with more pages than allowed. Useful on shared instances or Hugging Face Spaces to cap processing time.
- **`NGINX_MAX_BODY_SIZE`** (default `200M`) — nginx-level body cap, applied before the request reaches the backend. Defaults to `200M` so `MAX_FILE_SIZE_MB` is always the effective limit. Use nginx format (`50M`, `1G`, `0` for unlimited).
Both limits are exposed in the `/api/health` endpoint so the frontend can display them to the user before upload. Set either to `0` to disable the corresponding check. Both application limits are exposed in the `/api/health` endpoint so the frontend can display them to the user before upload. Set either to `0` to disable the corresponding check.
## Ingestion Pipeline (opt-in) ## Ingestion Pipeline (opt-in)

View file

@ -117,6 +117,8 @@ services:
context: ./frontend context: ./frontend
ports: ports:
- "3000:80" - "3000:80"
environment:
NGINX_MAX_BODY_SIZE: ${NGINX_MAX_BODY_SIZE:-200M}
depends_on: depends_on:
- document-parser - document-parser

View file

@ -9,6 +9,8 @@ RUN npm run build
FROM nginx:alpine FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf COPY nginx.conf.template /etc/nginx/templates/default.conf.template
ENV NGINX_MAX_BODY_SIZE=200M
EXPOSE 80 EXPOSE 80

View file

@ -20,6 +20,6 @@ server {
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 900s; proxy_read_timeout 900s;
proxy_send_timeout 900s; proxy_send_timeout 900s;
client_max_body_size 5M; client_max_body_size ${NGINX_MAX_BODY_SIZE};
} }
} }

View file

@ -20,6 +20,6 @@ server {
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 900s; proxy_read_timeout 900s;
proxy_send_timeout 900s; proxy_send_timeout 900s;
client_max_body_size 5M; client_max_body_size ${NGINX_MAX_BODY_SIZE};
} }
} }