Skip to content

Configuration

Every setting is an environment variable. Copy .env.example and adjust.

This table is checked against the code

scripts/check_docs_match_code.py fails CI if the code reads a variable this table does not list, or if the table lists one the code no longer reads. It exists because this documentation drifted badly once before.

Required

VariableEffectDefault
SECRET_KEYSigns the session cookie. The app refuses to start without it. Generate with python -c 'import secrets; print(secrets.token_hex(32))'.

A key generated per process would differ in every gunicorn worker, so a conversion started on one worker would be invisible to the next request, and every restart would invalidate every session. Two escape hatches exist for local work only: FLASK_ENV=development and PDF_OCR_TESTING=1. Never use either in a deployment.

Serving

VariableEffectDefault
PORTPort to listen on.8011
WEB_CONCURRENCYgunicorn worker processes. A conversion occupies one for its duration.2
WEB_THREADSgunicorn threads per worker.4
WEB_TIMEOUTgunicorn request timeout in seconds. Must cover a full upload, not a full conversion — conversions run in the background.120
SESSION_COOKIE_SECUREtrue when serving over HTTPS: marks the cookie Secure and enables HSTS. Setting it while serving plain HTTP makes the browser discard the cookie.false

The three WEB_* variables are read by entrypoint.sh, not by the application, so they apply to the container and to any gunicorn invocation that uses that script.

Limits

VariableEffectDefault
MAX_UPLOAD_MBUpload size limit. Larger requests get a 413.64
MAX_PAGESMaximum pages per PDF. A longer document is rejected before rendering.200
RENDER_BATCH_SIZEPages rendered per Poppler call. This is what bounds peak memory — the whole document is never in memory at once.4
STALE_TASK_TIMEOUTSeconds without progress before a conversion is reported as failed rather than left pending.1800

All four are positive integers; a malformed value fails at startup with a message naming the variable rather than a bare ValueError.

Storage and logging

VariableEffectDefault
UPLOAD_FOLDERWhere uploads, results and task records live. Mount your volume here.uploads
LOG_LEVELPython logging level.INFO
LOG_FILEIf set, also log to this file, rotating at 10 MB with 3 backups. Unset means stdout only.unset

Logging to stdout is the default because that is what an orchestrator collects, and because a read-only or non-writable working directory should not stop the app from booting.

Environment

VariableEffectDefault
DOCKER_ENVtrue skips the local Tesseract and Poppler probes. Set inside the image, where both are known to be present.false
FLASK_ENVdevelopment runs without SECRET_KEY and enables the Werkzeug debugger.unset

FLASK_ENV=development is remote code execution

The Werkzeug debugger executes arbitrary Python from the browser. It exists for local development only.