Skip to content

Environment Variable Configuration

OpenRAG provides a large range of environment variables that allow you to customize and configure various aspects of the application. This page serves as a comprehensive reference for all available environment variables, providing their types, default values, and descriptions. As new variables are introduced, this page will be updated to reflect the growing configuration options.

Openrag loads all files into a pivot markdown file format before proceeding to chunking. Some environment variables can be configured to customized this pipeline

VariableTypeDefaultDescription
IMAGE_CAPTIONINGbooltrueIf true, an LLM is used to describe images and convert them into text using a specific prompt. The image in files are replaced by their descriptions
IMAGE_CAPTIONING_URLbooltrueIf true, HTTP/HTTPS image URLs in markdown files are fetched and described by the VLM.
SAVE_MARKDOWNboolfalseIf true, the pivot-format markdown produced during parsing is saved. Useful for debugging and verifying the correctness of the generated markdown.
SAVE_UPLOADED_FILESboolfalseWhen true, uploaded files are stored on disk. You must enable this option if you want Chainlit to show sources while chatting.
PDFLOADERstrPyMuPDFLoaderPDF parsing engine. PyMuPDFLoader (default) is a lightweight, fast, CPU-friendly backend for searchable PDFs. Switch to MarkerLoader for OCR / scanned documents, complex layouts and embedded images (heavier; GPU-friendly). Other options: DoclingLoader, DotsOCRLoader.
PARSE_TIMEOUTint3600Outer wall-clock bound (in seconds) for a single file’s parse stage, whichever loader runs it. Marker and Docling self-limit via their own timeouts, but PyMuPDFLoader has none — this bound stops a wedged parse from stalling indexing: the file fails and is reported instead.

These settings apply when MarkerLoader is selected (PDFLOADER=MarkerLoader; the default is PyMuPDFLoader). It can be configured using the following environment variables:

VariableTypeDefaultDescription
MARKER_POOL_SIZEint1Number of workers (typically 1 worker per cluster node)
MARKER_MAX_PROCESSESint2Number of subprocesses <-> Number of concurrent PDFs per worker (to increase depending on your available GPU resources)
MARKER_MAX_TASKS_PER_CHILDint20Number of tasks a child (PDF worker) has to process before it gets restarted to clean up memory leaks
MARKER_TIMEOUTint3600Timeout in seconds for marker processes
MARKER_PDFTEXT_WORKERSint2Number of PDF text extractor workers inside marker.
MARKER_CHUNK_SIZEint10Split large PDFs into chunks of this many pages for parallel processing across workers. Use <= 0 to deactivate chunking.

These settings apply when DoclingLoader is selected (PDFLOADER=DoclingLoader):

VariableTypeDefaultDescription
DOCLING_POOL_SIZEint1Number of Docling worker actors in the Ray pool
DOCLING_MAX_TASKS_PER_WORKERint2Maximum number of PDFs processed concurrently per Docling worker
DOCLING_NUM_GPUSfloat0.01Fraction of a GPU reserved per Docling worker in Ray’s resource accounting
OpenAI-Compatible OCR Loader Configuration
Section titled “OpenAI-Compatible OCR Loader Configuration”

Modern OCR pipelines increasingly rely on VLM-based OCR models (such as DeepSeek OCR, DotsOCR, or LightOn OCR) that convert PDF pages into images and feed them into vision-language models with specialized prompts.
This loader integrates that workflow by exposing an OpenAI-compatible API that accepts PDF image pages and returns structured text produced by the OCR-VLM model in Markdown.

The parameters below configure how the OCR loader communicates with the model server, handles retries, manages concurrency, and controls model sampling behavior.

VariableTypeDefaultDescription
OPENAI_LOADER_BASE_URLstringhttp://openai:8000/v1Base URL of the OCR loader (OpenAI-compatible endpoint).
OPENAI_LOADER_API_KEYstringEMPTYAPI key used to authenticate with the OCR service.
OPENAI_LOADER_MODELstringdotsocr-modelOCR VLM model to use (e.g., DotsOCR, DeepSeek OCR, LightOn OCR).
OPENAI_LOADER_TEMPERATUREfloat0.2Sampling temperature. Lower values produce more deterministic OCR results.
OPENAI_LOADER_TIMEOUTint180Maximum request duration (in seconds) before timing out.
OPENAI_LOADER_MAX_RETRIESint2Number of retry attempts for failed OCR requests.
OPENAI_LOADER_TOP_Pfloat0.9Nucleus sampling parameter that limits generation to the top-p probability mass.
OPENAI_LOADER_CONCURRENCY_LIMITint20Maximum number of OCR requests processed concurrently. Useful for multi-page PDF workloads.
OPENAI_LOADER_ENABLE_THINKINGboolunsetOptional chat-template control for OCR VLM models that support enable_thinking; leave unset for Mistral tokenizers, set false to suppress Qwen-style reasoning traces.

OpenRAG provides two deployment options for audio transcription, configurable via the AUDIOLOADER environment variable:

VariableTypeDefaultDescription
AUDIOLOADERstrLocalWhisperLoaderSpecifies the audio loader implementation. Options: LocalWhisperLoader (bundled Whisper service) or OpenAIAudioLoader (external OpenAI API)
Local Whisper Loader ( LocalWhisperLoader )
Section titled “Local Whisper Loader ( LocalWhisperLoader )”

For local whisper loader, here are the options to use

VariableTypeDefaultDescription
WHISPER_MODELstrbaseThe whisper multilingual model to use depending on available resources. Other options: base, small, large, large-v3, etc.
WHISPER_N_WORKERSint2Number of whisper workers
WHISPER_CONCURRENCY_PER_WORKERint2Maximum number of audio transcription tasks processed concurrently by each Whisper worker.
WHISPER_NUM_GPUSfloat0.01Fraction of a GPU reserved per Whisper worker in Ray’s resource accounting.
OpenAI-compatible audio Loader ( OpenAIAudioLoader )
Section titled “OpenAI-compatible audio Loader ( OpenAIAudioLoader )”

The OpenAIAudioLoader option, allows to use openai-compatible audio endpoint/service to transcribe audio endpoint by providing the following variables: TRANSCRIBER_BASE_URL, TRANSCRIBER_API_KEY and TRANSCRIBER_MODEL

The audio is automatically segmented into chunks using silence detection, then transcribes these chunks in parallel for optimal speed and accuracy.

Here are some other variables related to openai-compatible endpoint.

VariableTypeDefaultDescription
TRANSCRIBER_BASE_URLstrhttp://transcriber:8000/v1Base URL for the transcriber API (OpenAI-compatible endpoint).
TRANSCRIBER_API_KEYstrEMPTYAuthentication key for transcriber service requests.
TRANSCRIBER_MODELstropenai/whisper-large-v3-turboWhisper model identifier served by VLLM for speech-to-text conversion. Other options: openai/whisper-small, openai/whisper-large-v3-turbo, etc.
TRANSCRIBER_MAX_CONCURRENT_CHUNKSint20Maximum number of audio chunks processed simultaneously. Increasing this value improves throughput when sufficient GPU resources are available.
TRANSCRIBER_TIMEOUTint3600Maximum duration in seconds allowed for a single transcription request.
TRANSCRIBER_DIRECT_UPLOAD_SUFFIXESstr.wav|.flac|.ogg|.mp3|.mp4|.m4a|.webm|.mpeg|.mpgaPipe-delimited list of audio file suffixes uploaded to the transcriber as-is (no WAV conversion). Other formats are re-encoded to WAV before upload. Trim this list when your transcriber backend (e.g. vLLM/libsndfile) only accepts a subset.
USE_WHISPER_LANG_DETECTORbooltrueWhen enabled, uses a local Whisper-based language detector to identify the source audio language before transcription.
TRANSCRIBER_PORTint8002Host port the bundled vLLM Whisper service (TRANSCRIBER_COMPOSE=extern/transcriber.yaml) is published on (maps to container port 8000). Only read once you uncomment the ports: mapping in that compose include — by default the service is reachable over the Docker network only.
VariableTypeDefaultDescription
CHUNKERstrrecursive_splitterDefines the chunking strategy: recursive_splitter.
CONTEXTUAL_RETRIEVALbooltrueEnables contextual retrieval to chunk context, a technique introduced by Anthropic to improve retrieval performance (Contextual Retrieval)
CHUNK_SIZEint512Maximum size (in characters) of each chunk.
CHUNK_OVERLAP_RATEfloat0.2Percentage of overlap between consecutive chunks.
CONTEXTUALIZATION_TIMEOUTint120Timeout in seconds for individual chunk contextualization LLM calls. Prevents long-running contextualization tasks from blocking the system.
MAX_CONCURRENT_CONTEXTUALIZATIONint10Maximum number of concurrent chunk contextualization tasks. Limits parallel LLM requests to prevent CPU exhaustion during batch indexing.

After files are converted to Markdown, only the text content is chunked. Image descriptions and Markdown tables are not chunked.

Chunker strategies:

  • recursive_splitter: Uses hierarchical text structure (sections, paragraphs, sentences). Based on RecursiveCharacterTextSplitter, it preserves natural boundaries whenever possible while ensuring chunks never exceeding the CHUNK_SIZE.

Our embedder is OpenAI-compatible and runs on a VLLM instance configured with the following variables:

VariableTypeDefaultDescription
EMBEDDER_MODEL_NAMEstrjinaai/jina-embeddings-v3HuggingFace Embedding model served by VLLM .i.e Qwen/Qwen3-Embedding-0.6B or jinaai/jina-embeddings-v3
EMBEDDER_BASE_URLstrhttp://vllm:8000/v1Base URL of the embedder (OpenAI-style).
EMBEDDER_API_KEYstrEMPTYAPI key for authenticating embedder calls.
MAX_MODEL_LENint2047Maximum context length (in tokens) supported by the embedding model. Chunks exceeding this limit are truncated (truncate_prompt_tokens = this value − 1). Keep it below the model’s real context boundary.
EMBEDDER_TIMEOUTfloat120.0Per-request HTTP timeout (in seconds) for embedding calls. Raise it for slow remote endpoints.
EMBEDDER_BATCH_SIZEint32Number of chunks sent per embedding request; large documents are split into batches of this size.
EMBEDDER_CONCURRENCYint4Maximum number of embedding requests in flight at once.

If you prefer to use an external embedding service, simply comment out the embedder service in the docker-compose.yaml and provide the variables above in your environment.

Our system uses two databases that work together:

  • Vector Database (VDB)

The vector database stores embeddings and is configured using the following environment variables:

VariableTypeDefaultDescription
VDB_HOSTstrmilvusHostname of the vector database service
VDB_PORTint19530Port on which the vector database listens
VDB_CONNECTOR_NAMEstrmilvusConnector/driver to use for the vector DB. Currently only milvus is implemented
VDB_COLLECTION_NAMEstrvdb_testName of the collection storing embeddings
VDB_HYBRID_SEARCHbooltrueTo activate hybrid search (semantic similarity + Keyword search)
VDB_ENABLE_INSERTIONbooltrueEnable or disable vector database insertion. When disabled, documents are processed but not inserted into Milvus. Useful for testing.
VDB_TIMEOUTfloat120.0Per-request timeout (seconds) applied to the Milvus sync and async clients

These variables can be overridden when using an external vector database service.

  • Relational Database (RDB)

The vector database implementation relies on an underlying PostgreSQL database that stores metadata about partitions and their owners (users). For more information about the data structure, see the data model.

The PostgreSQL database is configured using the following environment variables:

VariableTypeDefaultDescription
POSTGRES_HOSTstrrdbHostname of the PostgreSQL database service
POSTGRES_PORTint5432Port on which the PostgreSQL database listens
POSTGRES_USERstrrootUsername for database authentication
POSTGRES_PASSWORDstrroot_passwordPassword for database authentication
POSTGRES_DATABASEstrpartitions_for_collection_<VDB_COLLECTION_NAME>Database used for OpenRAG relational metadata. If unset, OpenRAG derives the historical name from the vector collection.
POSTGRES_AUTO_CREATE_DBbooltrueCreates the database automatically when it is missing. Keep this for local compose; set it to false for managed Postgres where the app role has no CREATEDB.
POSTGRES_RUN_MIGRATIONSbooltrueRuns Alembic migrations during app startup. Set it to false when migrations are applied by a deployment Job or init step.
POSTGRES_POOL_MIN_SIZEint5Minimum size of the async PostgreSQL connection pool.
POSTGRES_POOL_MAX_SIZEint20Maximum size of the async PostgreSQL connection pool.
POSTGRES_COMMAND_TIMEOUTint30Timeout in seconds for PostgreSQL commands issued through the async pool.
  • Object Storage (MinIO)

Milvus stores its data in a MinIO object store, whose credentials are required (no default) — the compose stack refuses to start if they are unset. Generate strong random values (e.g. openssl rand -hex 16). The same values are shared between the minio service and Milvus, so both sides must match.

VariableTypeDefaultDescription
MINIO_ACCESS_KEYstr(required)MinIO access key, shared by the minio service and Milvus. No default.
MINIO_SECRET_KEYstr(required)MinIO secret key, shared by the minio service and Milvus. No default.

The main Docker Compose stack keeps the historical host-path defaults. Set these variables when you want to move state elsewhere, including Docker named volumes.

When using host paths with the non-root API image, make sure the mounted directories are writable by the container user. If that is not practical for your deployment, use the named-volume profile instead.

For an opt-in named-volume profile, copy the values from infra/compose/.env.named-volumes.example into your .env.

VariableDefaultDescription
DATA_VOLUME../../dataOpenRAG uploaded files and app data mounted at /app/data.
LOG_VOLUME../../logsOpenRAG logs mounted at /app/logs.
MODEL_WEIGHTS_VOLUME~/.cache/huggingfaceModel cache mounted at /app/model_weights.
VLLM_CACHE/root/.cache/huggingfaceHugging Face cache used by vLLM, reranker, and transcriber services.
DB_VOLUME../../dbPostgreSQL data mounted at /var/lib/postgresql/data.
MILVUS_VOLUME_DIRECTORY./volumesParent directory for Milvus, etcd, and MinIO host-path storage.
MILVUS_COMPOSEmilvus/milvus.yamlMilvus compose include. Use milvus/milvus.named-volumes.yaml for the named-volume profile.
ETCD_VOLUMEetcdMilvus etcd named volume, used only with MILVUS_COMPOSE=milvus/milvus.named-volumes.yaml.
MINIO_VOLUMEminioMilvus object storage named volume, used only with MILVUS_COMPOSE=milvus/milvus.named-volumes.yaml.
MILVUS_VOLUMEmilvusMilvus named volume, used only with MILVUS_COMPOSE=milvus/milvus.named-volumes.yaml.

The system uses two types of language models:

  • LLM (Large Language Model): The primary model for text generation and chat interactions
  • VLM (Vision Language Model): Used for describing images (see IMAGE_CAPTIONING) and, to reduce load on the primary LLM, also handles contextualization tasks (see CONTEXTUAL_RETRIEVAL)

These are external services to provide !!!

VariableTypeDefaultDescription
BASE_URLstr(required)Base URL of the LLM API endpoint
MODELstr(required)Model identifier for the LLM
API_KEYstr(unset)API key for authenticating with the LLM service
LLM_ENABLE_THINKINGbool(unset)Optional chat-template control for models that support enable_thinking; leave unset for Mistral tokenizers, set false to suppress Qwen-style reasoning traces
LLM_SEMAPHOREint10Maximum number of concurrent requests to allow for the LLM service
MAX_LLM_CONTEXT_SIZEint8192Fallback maximum token limit for chat/completion requests. At startup, the /v1/models endpoint is queried for the model’s max_model_len; if that query fails this value is used instead. Requests whose total token count (prompt + max_tokens) exceeds the limit are rejected with a 413 error.
MAX_OUTPUT_TOKENSint1024Default output-token budget (max_tokens) applied to chat completions when the request doesn’t set one explicitly.
VariableTypeDefaultDescription
VLM_BASE_URLstr(required)Base URL of the VLM API endpoint
VLM_MODELstr(required)Model identifier for the VLM
VLM_API_KEYstr(unset)API key for authenticating with the VLM service
VLM_ENABLE_THINKINGbool(unset)Optional chat-template control for models that support enable_thinking; leave unset for Mistral tokenizers, set false to suppress Qwen-style reasoning traces
VLM_SEMAPHOREint10Maximum number of concurrent requests to allow for the VLM service
VariableTypeDefaultDescription
RAG_MODEstrChatBotRagHow the pipeline turns the conversation into search queries. ChatBotRag (default) uses the LLM and the chat history to generate contextualized search queries; SimpleRag skips query generation and searches directly on the raw last user message.

The retriever fetches relevant documents from the vector database based on query similarity. Retrieved documents are then optionally reranked to improve relevance.

VariableTypeDefaultDescription
RETRIEVER_TYPEstrsingleRetrieval strategy to use. Options: single, multiQuery, hyde
RETRIEVER_TOP_Kint50Number of documents to retrieve before reranking.
SIMILARITY_THRESHOLDfloat0.6Minimum similarity score (0.0-1.0) for document retrieval. Documents below this threshold are filtered out
WITH_SURROUNDING_CHUNKSboolfalseWhen enabled, retrieves adjacent chunks (preceding and following) for each matched document to provide additional context.
INCLUDE_RELATEDbooltrueExpand results with chunks from files sharing the matched file’s relationship_id (see Linked files).
INCLUDE_ANCESTORSbooltrueExpand results with chunks from ancestor files in the parent/child file hierarchy (see Linked files).
RELATED_LIMITint10Maximum number of related/ancestor chunks fetched per matched result when expansion is enabled.
MAX_DEPTHint10Maximum ancestor depth traversed when INCLUDE_ANCESTORS is enabled.
RETRIEVER_ALLOW_FILTERLESS_FALLBACKbooltrueWhen a temporally-filtered retrieval returns no documents, re-run the query without the filter. Set to false for strict temporal retrieval.
StrategyDescription
singleStandard semantic search using the original query. Fast and efficient for most queries
multiQueryGenerates multiple query variations to improve recall. Better coverage for ambiguous or complex questions
hydeHypothetical Document Embeddings - generates a hypothetical answer then searches for similar documents

The reranker enhances search quality by re-scoring and reordering retrieved documents according to their relevance to the user’s query. Three providers are supported: Infinity (default), OpenAI-compatible endpoints, and Hugging Face Text Embeddings Inference (TEI).

VariableTypeDefaultDescription
RERANKER_ENABLEDbooltrueEnable or disable the reranking mechanism
RERANKER_PROVIDERstrinfinityReranker backend to use. Accepted values: infinity, openai, tei
RERANKER_MODELstrAlibaba-NLP/gte-multilingual-reranker-baseModel used for reranking documents. Ignored by the tei provider (a TEI instance serves a single fixed model)
RERANKER_TOP_Kint10Number of top documents to return after reranking. Increase for better results if your LLM has a wider context window
RERANKER_BASE_URLstrhttp://reranker:7997Base URL of the reranker service
RERANKER_API_KEYstrEMPTYAPI key for the reranker service, sent as a Bearer token when set. Whether a key is required depends on your endpoint
RERANKER_TIMEOUTfloat60.0HTTP timeout in seconds for reranker requests
RERANKER_SEMAPHOREint5Maximum number of concurrent reranking requests. Adjust based on your server capacity
RERANKER_PORTint7997 (infinity) / 8000 (openai)Host port the bundled reranker service is published on. Only read by the compose includes (extern/reranker/*.yaml), and only once you uncomment their ports: mapping — by default the service is reachable over the Docker network only, so publishing it is just for host-side debugging or direct calls.
ProviderRERANKER_PROVIDER valueDescription
InfinityinfinityUses the Infinity server via its native client. Default port: 7997
OpenAI-compatibleopenaiUses any reranker endpoint implementing the {model, query, documents, top_n}{results: [...]} rerank contract (e.g. vLLM, LiteLLM). Default port: 8000
TEIteiUses a Hugging Face Text Embeddings Inference server via its native /rerank API (which is not OpenAI-compatible: texts instead of documents, no model/top_n fields, bare-array response). Default port: 8080. Requests are batched to 32 texts to fit TEI’s default --max-client-batch-size

The RAG pipeline ships with preconfigured prompts bundled inside the package at openrag/prompts/templates. Here are the available Prompt Templates in that folder.

Template FilePurpose
sys_prompt_tmpl.txtSystem prompt that defines the assistant’s behavior and role
spoken_style_answer_tmpl.txtTemplate for converting responses to a more natural, conversational spoken style (oral / audio type of answer)
query_contextualizer_tmpl.txtTemplate for adding context to user queries
chunk_contextualizer_tmpl.txtTemplate for contextualizing document chunks during indexing
image_captioning_tmpl.txtTemplate for generating image descriptions using the VLM
hyde.txtHypothetical Document Embeddings (HyDE) query expansion template
multi_query_pmpt_tmpl.txtTemplate for generating multiple query variations

To customize prompt:

  1. Copy the bundled templates: Copy openrag/prompts/templates to a folder of your choice
  2. Create your custom folder: Rename it to something meaningful, e.g., my_prompt
  3. Modify the prompts: Edit any prompt templates within your new folder
  4. Update configuration: Point PROMPTS_DIR at your custom prompts directory
.env
# Use custom prompts
export PROMPTS_DIR=/path/to/my_prompt
VariableTypeDefaultDescription
PROMPTS_DIRstr(bundled openrag/prompts/templates)Path to a directory of prompt templates. Unset uses the templates bundled in the package; set it only to override with a custom directory.

Our application uses Loguru with custom formatting. Log messages appear in two places:

  • Terminal (stderr): Human-readable formatted output
  • Log file (logs/app.json): JSON format for monitoring tools like Grafana. This file resides at the mounted folder ./logs

Terminal output follows this format:

Logging message in the terminal...
LEVEL | module:function:line - message [context_key=value]

There are several logging levels available (TRACE, DEBUG, INFO, SUCCESS, WARNING, ERROR, CRITICAL). Only the levels intended for use in this project are documented here.

LevelWhat You’ll See in Logs
WARNINGPotential issues that don’t stop execution: approaching rate limits, deprecated features used, retryable failures, configuration concerns. Review these periodically.
DEBUGDetailed diagnostic information including variable states, intermediate processing steps, and function entry/exit points. Useful during development and troubleshooting.
INFOStandard operational messages showing normal application behavior: server startup, request handling, major workflow stages. This is the typical production level.

Set the logging level via environment variable:

.env
# Show only warnings and errors
LOG_LEVEL=WARNING
# Show detailed debug information (use in dev and pre-prod)
LOG_LEVEL=DEBUG
# Production default (informational messages)
LOG_LEVEL=INFO
  • Rotation: Files rotate automatically at 10 MB
  • Retention: Logs kept for 10 days
  • Format: JSON for easy parsing and ingestion into monitoring systems
  • Async: Queued writing (enqueue=True) prevents blocking operations

Ray is used for distributed task processing and parallel execution in the RAG pipeline. This configuration controls resource allocation, concurrency limits, and serving options.

VariableTypeDefaultDescription
RAY_POOL_SIZEint1Number of indexer worker actors in the pool. Total indexing capacity = RAY_POOL_SIZE × RAY_MAX_TASKS_PER_WORKER.
RAY_MAX_TASKS_PER_WORKERint50Maximum number of files processed concurrently per indexer worker actor
RAY_DASHBOARD_PORTint8265Ray Dashboard port used for monitoring. In production, comment out this line to avoid exposing the port, as it may introduce security vulnerabilities.
RAY_DASHBOARD_HOSTstr127.0.0.1Interface the embedded Ray dashboard binds to. Defaults to loopback because the Ray dashboard/job-submission API is unauthenticated (CVE-2023-48022). Set to 0.0.0.0 only when the dashboard port is firewalled or sits behind an authenticating proxy. Ignored when RAY_ADDRESS is set.
RAY_ADDRESSstr(unset)When set, attach to an external Ray cluster at this address (e.g. ray://HEAD_IP:10001) instead of starting an embedded cluster in-process. In this mode the app does not start a local dashboard — the head node owns it. See Ray Cluster deployment.
VariableTypevalueDescription
RAY_DEDUP_LOGSnumber0Turns off Ray log deduplication that appears across multiple processes. Set to 0 to see all logs from each process.
RAY_ENABLE_RECORD_ACTOR_TASK_LOGGINGnumber1Enables logs at task level in the Ray dashboard for better debugging and monitoring.
RAY_task_retry_delay_msnumber3000Delay (in milliseconds) before retrying a failed task. Controls the wait time between retry attempts.
RAY_ENABLE_UV_RUN_RUNTIME_ENVnumber0Controls UV runtime environment integration. Critical: Must be set to 0 when using the newest version of UV to avoid compatibility issues.
RAY_memory_monitor_refresh_msnumber250 msTo control the frequency of memory usage checks and task or actor termination if needed. If you set this value to 0, task killing is disabled.

Ray Serve enables deployment of the FastAPI app as a horizontally scalable service.

By default (ENABLE_RAY_SERVE=false) OpenRAG runs under uvicorn with a single worker. This is intentional: the app initializes Ray and its named actors (Indexer, Vectordb, TaskStateManager, …) at import time, so a second uvicorn worker would start its own isolated Ray cluster with duplicate actors, fragmenting task state and vector-DB access. Concurrency within the single worker comes from the async app and from Ray itself — not from multiple uvicorn workers (there is intentionally no API_NUM_WORKERS knob).

To scale the HTTP layer, enable Ray Serve — it runs RAY_SERVE_NUM_REPLICAS replicas inside one shared Ray cluster:

Terminal window
ENABLE_RAY_SERVE=true
RAY_SERVE_NUM_REPLICAS=4

For multi-node distributed deployments, see Distributed Deployment in a Ray Cluster.

VariableTypeDefaultDescription
ENABLE_RAY_SERVEboolfalseEnable Ray Serve deployment mode
RAY_SERVE_NUM_REPLICASint1Number of service replicas for load balancing
RAY_SERVE_HOSTstr0.0.0.0Host address for the Ray Serve deployment
RAY_SERVE_PORTint8080Port for the Ray Serve FastAPI endpoint
CHAINLIT_PORTint8090Port for the Chainlit UI interface if ray serve is enable ENABLE_RAY_SERVE. If not chainlit UI is simply a subroute (/chainlit see this) of the FastAPI base_url

Web search allows the LLM to augment RAG document context with live web results. It is disabled by default — set WEBSEARCH_API_TOKEN to enable it.

VariableTypeDefaultDescription
WEBSEARCH_PROVIDERstrstaanWeb search provider to use. Currently supported: staan.
WEBSEARCH_API_TOKENstr""API token for the web search provider. If empty, web search is disabled.
WEBSEARCH_BASE_URLstr(provider default)Base URL of the web search provider API.
WEBSEARCH_TOP_Kint5Number of web search results to return.
WEBSEARCH_LANGstrfr-FRLanguage/market code for web search queries.
WEBSEARCH_MAX_TOKENSint2000Maximum token budget for all web sources combined in the LLM context. This budget is reserved from the global context window when web results are present.
WEBSEARCH_FETCH_CONTENTbooltrueWhen enabled, fetches actual page content from the top URLs instead of relying on short search snippets.
WEBSEARCH_FETCH_MAX_RESULTSint3Number of top URLs to fetch content from (the remaining results use their search snippet).
WEBSEARCH_FETCH_TIMEOUTfloat1.0Per-URL timeout in seconds for content fetching. URLs that don’t respond within this time fall back to their snippet.
WEBSEARCH_FETCH_MAX_TOKENSint500Maximum approximate tokens of content to extract per page. Content is truncated at word boundaries.
WEBSEARCH_FETCH_VERIFY_SSLboolfalseWhether to verify SSL certificates when fetching page content.

The map & reduce mechanism processes documents by fetching chunks (map phase), filtering out irrelevant ones and summarizing relevant content (reduce phase) with respect to the user’s query. The algorithm works as follows:

  1. Initially fetches a batch of documents for processing
  2. Evaluates relevance and continues expanding the search if needed
  3. Stops expansion when the last MAP_REDUCE_EXPANSION_BATCH_SIZE chunks are all irrelevant
  4. Otherwise, continues fetching additional documents up to MAP_REDUCE_MAX_TOTAL_DOCUMENTS

When MAP_REDUCE_DEBUG is enabled, the mechanism logs detailed information to ./logs/map_reduce.md.

VariableTypeDefaultDescription
MAP_REDUCE_INITIAL_BATCH_SIZEint10Number of documents to process in the initial mapping phase
MAP_REDUCE_EXPANSION_BATCH_SIZEint5Number of additional documents to fetch when expanding the search (also used as the threshold for stopping)
MAP_REDUCE_MAX_TOTAL_DOCUMENTSint20Maximum total number of documents (chunks) to process across all iterations
MAP_REDUCE_DEBUGboolfalseEnable debug logging for map & reduce operations. Logs are written to ./logs/map_reduce.md

By default, our API (FastAPI) uses uvicorn for deployment. One can opt in to use Ray Serve for scalability (see the ray serve configuration)

The following environment variables configure the FastAPI server and control access permissions:

VariableTypeDefaultDescription
APP_PORTnumber8000Port number on which the FastAPI application listens for incoming requests.
AUTH_TOKENstringEMPTYAuthentication token used to bootstrap the admin user and access protected API endpoints. If it is empty, the API fails closed unless ALLOW_NO_AUTH=true is explicitly set for local development.
ALLOW_NO_AUTHbooleanfalseEnables the no-auth local development bypass when AUTH_MODE=token and AUTH_TOKEN is unset. Never enable this in production.
SUPER_ADMIN_MODEbooleanfalseEnables super admin privileges when set to true, granting unrestricted access to all operations and bypassing standard access controls. This is for debugging
DEFAULT_FILE_QUOTAint-1Default per-user file quota. <0 disables quotas globally; >=0 sets the default limit when a user has no explicit quota.
PREFERRED_URL_SCHEMEstringnullURL scheme (http or https) used when generating URLs in API responses (e.g., task_status_url). When running behind a reverse proxy that terminates SSL, set this to https to ensure generated URLs use the correct scheme. If unset, the scheme from the incoming request is used.
CORS_EXTRA_ORIGINSstring(unset)Semicolon-separated list of additional origins allowed by CORS (e.g. https://app.example.com;https://other.example.com). Extends the default list without replacing it.
UVICORN_FORWARDED_ALLOW_IPSstring127.0.0.1Comma-separated CIDRs/IPs (or *) whose X-Forwarded-* headers uvicorn trusts. Required when OpenRAG runs behind a TLS-terminating reverse proxy that lives outside loopback (typical docker-compose / k8s); otherwise X-Forwarded-Proto is dropped and OIDC cookies ship with Secure=False even over HTTPS.
MAX_UPLOAD_SIZE_MBint1024Maximum accepted upload size, in MB. 0 or a negative value means unlimited.
MAX_PARTITIONS_PER_USERint100Maximum number of partitions a non-admin user may own. -1 disables the cap (unlimited). Admin users always bypass it.
APP_UIDint1000UID the API container drops to before running the app. Override when your host user is not UID 1000 and bind-mounted folders (data/, logs/) would otherwise not be writable by the container user.
WITH_OPENAI_APIbooltrueMount the OpenAI-compatible routers (/v1/*). Note: they stay mounted while WITH_CHAINLIT_UI=true, since Chainlit consumes them.
WITH_CHAINLIT_UIbooltrueMount the bundled Chainlit chat UI under /chainlit (plus its root assets, e.g. the pdf.js worker for source previews).

Per-identity request rate limiting, tiered by path prefix. Requests are keyed on the authenticated user id, falling back to the client IP for unauthenticated paths (/auth/*). Admin users bypass rate limiting entirely. Limits use a moving window and are enforced per worker/replica — front OpenRAG with shared storage (e.g. Redis) if you scale out and need a global budget. Exceeding a limit returns 429 with a Retry-After header.

Limit values use the <count>/<period> format from the limits library (e.g. 120/minute, 10/second).

VariableTypeDefaultDescription
RATE_LIMIT_ENABLEDbooltrueMaster switch for request rate limiting. When false, no limits are applied and malformed limit values are ignored.
RATE_LIMIT_DEFAULTstr600/minuteLimit applied to every path except the tiers below.
RATE_LIMIT_AUTHstr60/minuteLimit for /auth/* (login/callback/logout). Keyed on client IP because callers are unauthenticated there — keep it high enough that a shared corporate/NAT egress IP does not throttle a legitimate login rush.
RATE_LIMIT_CHATstr120/minuteLimit for /v1/* (chat completions, tools).
RATE_LIMIT_AUTH_FAILUREstrRATE_LIMIT_AUTH, else 20/minuteSeparate, stricter budget for failed authentication attempts, keyed by client IP (brute-force protection). Falls back to RATE_LIMIT_AUTH when unset, then to 20/minute. Disabled together with RATE_LIMIT_ENABLED=false.

The admin UI is a React SPA (the document ingestion, indexing & management interface) served by the admin-ui (nginx) container. Every VITE_* setting is baked into the bundle at build time — Vite inlines them when the image is built, so they are not read at container runtime. After changing one, rebuild the image: docker compose build admin-ui.

How the UI reaches the API (same-origin). The browser only ever talks to a single origin — http://<host>:ADMIN_UI_PORT. nginx inside the admin-ui container serves the static SPA under /app/ and reverse-proxies every other path (/v1, /auth, /chainlit, /indexer, …) to the API at openrag:8080 over the Docker network. Because the bundle is built with VITE_API_BASE_URL="", its API calls are relative, so they land back on that same origin — there is no CORS, and the OIDC openrag_session cookie is first-party. You don’t even need to publish the API’s own APP_PORT to the host; the UI reaches the backend internally over the compose network. Set VITE_API_BASE_URL only for a browser-direct build, where the SPA calls the API on a different origin — then also add that origin to CORS_EXTRA_ORIGINS.

flowchart TD
    B["Browser — single origin<br/>http://HOST:ADMIN_UI_PORT"]
    subgraph AUC["admin-ui container"]
        N{"nginx :8080<br/>route by path"}
        SPA["Static SPA files<br/>(/app/*)"]
    end
    API["openrag:8080<br/>API service · Docker network"]

    B -->|"GET /app/ (page load)"| N
    B -->|"fetch /v1, /auth, /users, /indexer …<br/>relative → same origin, no CORS"| N
    N -->|"/app/*"| SPA
    N -->|"everything else"| API
VariableTypeDefaultDescription
ADMIN_UI_PORTnumber8081Host port the admin UI (nginx) is published on. Serves /app/ and reverse-proxies /auth, /v1, /chainlit, … to the backend, so it is the OIDC front door (OIDC_REDIRECT_URI targets this port). Deploy-time (not a VITE_* build arg).
VITE_API_BASE_URLstring"" (same-origin)API base baked into the SPA. Empty (default) = same-origin: nginx reverse-proxies the API over the Docker network, so the UI works on any host/IP with no CORS. Set to an absolute URL only for a browser-direct build — then list the UI’s origin in CORS_EXTRA_ORIGINS.
VITE_BASE_PATHstring/app/Sub-path the SPA is served under; must match the nginx location.
VITE_GRAFANA_URLstring""Optional Grafana dashboard link shown on the admin System page.
VITE_APP_NAMEstringOpenRAGApplication display name used in the UI branding.
VITE_MOCK_APIbooleanfalseDevelopment only — serves in-browser MSW API mocks when true. Ignored in production builds.

See this for chainlit authentification

See this for chainlit data persistency

VariableTypeDefaultDescription
DEFAULT_LANGUAGEstrUI language for Chainlit and the Admin UI (e.g. en-US, fr). When unset, the browser language is used, with en-US as the final fallback.

OpenRAG ships a standalone Model Context Protocol server (openrag/api/mcp/server.py) that exposes retrieval to MCP clients. It runs as its own process (not part of the default compose stack). These variables configure the FastMCP transport binding and the search-tool defaults/bounds applied before a request reaches the retrieval service.

VariableTypeDefaultDescription
OPENRAG_MCP_SERVER_NAMEstrOpenRAG MCPDisplay name advertised by the MCP server.
OPENRAG_MCP_HOSTstr0.0.0.0Interface the MCP server binds to.
OPENRAG_MCP_PORTint8081Port the MCP server listens on.
OPENRAG_MCP_PATHstr/mcpHTTP path the MCP endpoint is served under.
OPENRAG_MCP_DEFAULT_TOP_Kint5Number of chunks the search tool returns when the caller doesn’t specify top_k.
OPENRAG_MCP_MAX_TOP_Kint50Upper bound clamped on a caller-supplied top_k.
OPENRAG_MCP_SIMILARITY_THRESHOLDfloat0.8Minimum similarity score for a chunk to be returned by the search tool.
OPENRAG_MCP_DOWNLOAD_TIMEOUTfloat30.0Timeout (seconds) for the server-side index_url fetch (SSRF/DoS hardening).
OPENRAG_MCP_MAX_DOWNLOAD_BYTESint104857600Maximum bytes downloaded by an index_url fetch. Default is 100 MiB.

Model-endpoint seed overrides (legacy aliases)

Section titled “Model-endpoint seed overrides (legacy aliases)”

On first startup, OpenRAG seeds its model-endpoint catalog from the canonical variables documented above. The following legacy aliases are still read at seed time for backward compatibility and, when set, take precedence over their canonical counterpart during that initial seeding only. Prefer the canonical variables in new deployments — do not set both.

Legacy aliasFalls back to (canonical)
LLM_ENDPOINTBASE_URL
LLM_MODELMODEL
VLM_ENDPOINTVLM_BASE_URL
EMBEDDER_ENDPOINTEMBEDDER_BASE_URL
EMBEDDING_MODELEMBEDDER_MODEL_NAME
RERANKER_ENDPOINTRERANKER_BASE_URL

(VLM_MODEL and RERANKER_MODEL are already the canonical names and are also used at seed time.)

Deployment-level knobs; most deployments never need to touch these — the compose stack drives the path variables through the storage volume variables instead.

VariableTypeDefaultDescription
OPENRAG_CONF_DIRstrbundled conf/Directory containing config.yaml. Override to run against a custom configuration tree.
DATA_DIRstr/app/data (container)Where uploaded files and app data are stored. In compose, relocate it via DATA_VOLUME rather than this variable.
DB_DIRstr/app/dbLocal database directory.
LOG_DIRstr/app/logsLog directory. In compose, relocate it via LOG_VOLUME rather than this variable.
OPENRAG_CONTAINER_STARTUP_TIMEOUTfloatmax(60, 4 × POSTGRES_COMMAND_TIMEOUT) (= 120 with defaults)Seconds the API’s service container (DB pools, Ray actors, …) is allowed to initialize at startup before the app fails fast.
OPENRAG_BANNERbooltrueSet to false to suppress the ASCII startup banner. Its colors also auto-disable under the standard NO_COLOR / TERM=dumb conventions.
UVICORN_RELOADboolfalseDevelopment only — starts uvicorn with --reload (auto-restart on code changes). Also forces a single worker. Never enable in production.

Read only by the opt-in monitoring compose file (infra/compose/monitoring.docker-compose.yaml):

VariableTypeDefaultDescription
GRAFANA_ADMIN_USERstradminGrafana admin username.
GRAFANA_ADMIN_PASSWORDstr(required)Grafana admin password — compose refuses to start the monitoring profile if unset.