Files
wehub-resource-sync 7a0da7932b
Backwards Compatibility / Verify Encryption Constants (push) Waiting to run
Backwards Compatibility / PyPI Version Compatibility (push) Waiting to run
Backwards Compatibility / Database Migration Tests (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Blocked by required conditions
Docker Tests (Consolidated) / detect-changes (push) Waiting to run
Docker Tests (Consolidated) / Build Test Image (push) Waiting to run
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Blocked by required conditions
Docker Tests (Consolidated) / Accessibility Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Unit Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Example Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / Production Image Smoke Test (push) Blocked by required conditions
Docker Tests (Consolidated) / Infrastructure Tests (push) Blocked by required conditions
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Waiting to run
OSV-Scanner (Scheduled) / scan-scheduled (push) Waiting to run
Create Release / test-gate (push) Blocked by required conditions
Create Release / release-gate (push) Blocked by required conditions
Create Release / ci-gate (push) Blocked by required conditions
Create Release / version-check (push) Waiting to run
Create Release / e2e-test-gate (push) Blocked by required conditions
Create Release / responsive-test-gate (push) Blocked by required conditions
Create Release / compat-test-gate (push) Blocked by required conditions
Create Release / compose-integration-gate (push) Blocked by required conditions
Create Release / vulture-gate (push) Blocked by required conditions
Create Release / build (push) Blocked by required conditions
Create Release / provenance (push) Blocked by required conditions
Create Release / prerelease-docker (push) Blocked by required conditions
Create Release / publish-docker (push) Blocked by required conditions
Create Release / create-release (push) Blocked by required conditions
Create Release / cleanup-changelog (push) Blocked by required conditions
Create Release / trigger-pypi (push) Blocked by required conditions
Create Release / monitor-pypi (push) Blocked by required conditions
Create Release / Clean up orphan prerelease tags and signatures (push) Blocked by required conditions
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

12 KiB

Configuring Local Deep Research with Environment Variables

Note: For most users, the Web UI Settings is the recommended way to configure Local Deep Research. Environment variables are primarily useful for Docker deployments, CI/CD pipelines, and server configurations where the web UI is not accessible during startup.

For a complete auto-generated reference of all settings, defaults, and environment variables, see CONFIGURATION.md.

You can override any configuration setting in Local Deep Research using environment variables. This is useful for:

  • Setting up multiple environments (development, production)
  • Changing settings without modifying configuration files
  • Providing sensitive information like API keys securely
  • Setting server ports for Docker or cloud deployments

Environment Variable Format

To override a setting, convert its key to uppercase, replace dots with underscores, and prefix with LDR_:

setting.key.name  →  LDR_SETTING_KEY_NAME

For example:

  • app.debugLDR_APP_DEBUG
  • llm.modelLDR_LLM_MODEL
  • search.toolLDR_SEARCH_TOOL

Important: Environment variables override UI settings and lock them — the setting becomes read-only in the UI until the environment variable is removed. For settings you may want to adjust later, use the Web UI instead.

Note on empty values: Empty environment variables (e.g., LDR_LLM_PROVIDER="") are treated as not set — they will not override anything and the setting remains editable in the UI. This is by design: deployment tools like Unraid and Docker Compose templates often create all environment variables even when fields are left blank. Only non-empty values act as overrides. To remove an override, delete the environment variable entirely rather than setting it to an empty string. To explicitly block a setting, set it to any non-empty invalid value (e.g., DISABLED).

For the complete list of all settings, their environment variable names, and default values, see CONFIGURATION.md.

API Keys

API keys are best set using environment variables for security. Only the LDR_ prefixed version is needed.

Security note: Setting an API key variable to an empty string (e.g., LDR_LLM_OPENAI_API_KEY="") does not block or clear the key — it is treated as unset, and the key remains editable in the UI. If a key is already stored in the database, it will still be used. To explicitly block a key, set it to any non-empty invalid value (e.g., DISABLED).

# LLM API keys
export LDR_LLM_OPENAI_API_KEY=your-openai-key-here
export LDR_LLM_ANTHROPIC_API_KEY=your-anthropic-key-here
export LDR_LLM_OPENROUTER_API_KEY=your-openrouter-key-here

# Search engine API keys
export LDR_SEARCH_ENGINE_WEB_BRAVE_API_KEY=your-brave-key-here
export LDR_SEARCH_ENGINE_WEB_SERPAPI_API_KEY=your-serpapi-key-here
export LDR_SEARCH_ENGINE_WEB_TAVILY_API_KEY=your-tavily-key-here

For the full list of API key environment variables, see CONFIGURATION.md.

LLM Provider Configuration

OpenRouter

OpenRouter provides access to 100+ models through an OpenAI-compatible API. To use OpenRouter:

  1. Get an API key from openrouter.ai
  2. Configure using one of these methods:

Method 1: Via Web UI (Recommended)

  • Navigate to Settings → LLM Provider
  • Select "OpenAI-Compatible Endpoint"
  • Set Endpoint URL to: https://openrouter.ai/api/v1
  • Enter your OpenRouter API key
  • Select your desired model

Method 2: Via Environment Variables

# Required environment variables for OpenRouter
export LDR_LLM_PROVIDER=openai_endpoint
export LDR_LLM_OPENAI_ENDPOINT_URL=https://openrouter.ai/api/v1
export LDR_LLM_OPENAI_ENDPOINT_API_KEY="<your-api-key>"
export LDR_LLM_MODEL=anthropic/claude-3.5-sonnet  # or any OpenRouter model

Method 3: Docker Compose

Add to your docker-compose.yml environment section:

services:
  local-deep-research:
    environment:
      - LDR_LLM_PROVIDER=openai_endpoint
      - LDR_LLM_OPENAI_ENDPOINT_URL=https://openrouter.ai/api/v1
      - LDR_LLM_OPENAI_ENDPOINT_API_KEY=<your-api-key>
      - LDR_LLM_MODEL=anthropic/claude-3.5-sonnet

Available Models: Browse models at openrouter.ai/models

Note: OpenRouter uses the OpenAI-compatible API, so you select "OpenAI-Compatible Endpoint" as the provider and change the endpoint URL to OpenRouter's API.

Other OpenAI-Compatible Providers

The same configuration pattern works for any OpenAI-compatible API service:

# Generic pattern for OpenAI-compatible APIs
export LDR_LLM_PROVIDER=openai_endpoint
export LDR_LLM_OPENAI_ENDPOINT_URL=https://your-provider.com/v1
export LDR_LLM_OPENAI_ENDPOINT_API_KEY="<your-api-key>"
export LDR_LLM_MODEL="<your-model-name>"

Docker Usage

For Docker deployments, you can pass environment variables when starting containers:

docker run -p 5000:5000 \
  -e LDR_LLM_OPENAI_API_KEY=your-api-key-here \
  -e LDR_SEARCH_TOOL=wikipedia \
  local-deep-research

Migrating from server_config.json

The server_config.json file is deprecated and will be removed in a future release. Migrate your settings to environment variables using this mapping:

server_config.json key Environment Variable
host LDR_WEB_HOST
port LDR_WEB_PORT
debug LDR_APP_DEBUG
use_https LDR_WEB_USE_HTTPS
allow_registrations LDR_APP_ALLOW_REGISTRATIONS
rate_limit_default LDR_SECURITY_RATE_LIMIT_DEFAULT
rate_limit_login LDR_SECURITY_RATE_LIMIT_LOGIN
rate_limit_registration LDR_SECURITY_RATE_LIMIT_REGISTRATION
rate_limit_settings LDR_SECURITY_RATE_LIMIT_SETTINGS

After setting the environment variables, delete server_config.json from your data directory. The web UI will show a warning banner while the file still exists.

Common Operations

Changing the Web Port

export LDR_WEB_PORT=8080  # Linux/Mac
set LDR_WEB_PORT=8080     # Windows

Note: LDR_APP_PORT is a separate setting for notification URL generation. To change the port the server listens on, use LDR_WEB_PORT. Requires server restart.

Setting API Keys

# Linux/Mac
export LDR_LLM_ANTHROPIC_API_KEY=your-api-key-here

# Windows
set LDR_LLM_ANTHROPIC_API_KEY=your-api-key-here

Changing Search Engine

export LDR_SEARCH_TOOL=wikipedia  # Linux/Mac
set LDR_SEARCH_TOOL=wikipedia     # Windows

Data Directory Location

By default, Local Deep Research stores all data (database, research outputs, cache, logs) in platform-specific user directories. You can override this location using the LDR_DATA_DIR environment variable:

# Linux/Mac
export LDR_DATA_DIR=/path/to/your/data/directory

# Windows
set LDR_DATA_DIR=C:\path\to\your\data\directory

All application data will be organized under this directory:

  • $LDR_DATA_DIR/ldr.db - Application database
  • $LDR_DATA_DIR/research_outputs/ - Research reports
  • $LDR_DATA_DIR/cache/ - Cached data
  • $LDR_DATA_DIR/logs/ - Application logs

Debug Logging (LDR_APP_DEBUG and LDR_LOGURU_DIAGNOSE)

LDR_APP_DEBUG=true raises the log level to DEBUG for more informative output. It does not, on its own, enable Loguru's diagnose mode, which renders the repr() of every local variable in every traceback frame on exceptions and can materialise credentials (API keys, the SQLCipher master password, Authorization headers) into your logs.

To opt into that variable-level detail, set LDR_LOGURU_DIAGNOSE=true in addition to LDR_APP_DEBUG=true. Keep it disabled in production; a warning is emitted whenever it is active.

# Verbose logs, no local-variable dumps (safe default for debugging)
export LDR_APP_DEBUG=true

# Full exception diagnostics including frame locals (NEVER in production)
export LDR_APP_DEBUG=true
export LDR_LOGURU_DIAGNOSE=true

Database Configuration (SQLCipher)

Database encryption settings are configured exclusively via environment variables (they cannot be changed through the Web UI). These settings are applied at database creation time and must remain consistent for the database to be accessible.

For the full list of database configuration variables, defaults, constraints, and deprecated aliases, see the Pre-Database (Env-Only) Settings section in CONFIGURATION.md.

Upload Size Limit

The per-file upload cap is read from LDR_SECURITY_UPLOAD_MAX_FILE_SIZE_MB at startup. The value is in megabytes; the default is 3072 MB (3 GB). Values must be positive integers; zero, negative, or non-integer values fall back to the default with a warning.

# Allow up to 5 GB per file
export LDR_SECURITY_UPLOAD_MAX_FILE_SIZE_MB=5120

# Tighten to 100 MB
export LDR_SECURITY_UPLOAD_MAX_FILE_SIZE_MB=100

This cap applies to both the research-upload and RAG-collection upload endpoints. A separate library-side setting (research_library.max_pdf_size_mb) controls whether a PDF that passes the upload cap can also be stored in the library — both default to 3 GB and should typically be raised or lowered together.

Memory usage stays bounded regardless of the cap: multipart uploads are spooled to disk above a 5 MB threshold (DiskSpoolingRequest.max_form_memory_size), so the per-file cap does not directly affect RAM consumption.

Requires a server restart to take effect.

CORS / WebSocket Security

These settings control Cross-Origin Resource Sharing (CORS) for API routes and WebSocket connections. For the full list of security environment variables and their defaults, see CONFIGURATION.md.

WebSocket connections also require an authenticated session in addition to passing the CORS check below. The CORS setting controls which origins may attempt a handshake; the auth requirement ensures only logged-in users can complete one.

Values:

  • * — Allow all origins (most permissive)
  • Empty string or unset — Same-origin only (most restrictive)
  • Comma-separated list — Allow specific origins only

Examples:

# Same-origin only (the default — leave both unset, shown here for clarity)
export LDR_SECURITY_WEBSOCKET_ALLOWED_ORIGINS=""

# Allow specific cross-origin front-ends (recommended when you need cross-origin)
export LDR_SECURITY_CORS_ALLOWED_ORIGINS="https://example.com,https://app.example.com"
export LDR_SECURITY_WEBSOCKET_ALLOWED_ORIGINS="https://example.com,https://app.example.com"

# Allow ALL origins — disables CORS/WebSocket origin checks.
# Trusted local/dev networks only; do not use in production.
export LDR_SECURITY_CORS_ALLOWED_ORIGINS="*"
export LDR_SECURITY_WEBSOCKET_ALLOWED_ORIGINS="*"

Docker Compose example:

services:
  local-deep-research:
    environment:
      # Same-origin is the secure default — omit these unless you serve the UI
      # from a different origin, then list it explicitly (avoid "*").
      - LDR_SECURITY_CORS_ALLOWED_ORIGINS=https://app.example.com
      - LDR_SECURITY_WEBSOCKET_ALLOWED_ORIGINS=https://app.example.com

Note: If WebSocket connections fail after upgrading to the same-origin default, the usual cause is a TLS-terminating reverse proxy that doesn't forward X-Forwarded-Proto (see the Socket.IO proxy snippet in troubleshooting — the same header is needed for secure cookies/HSTS). Otherwise, set LDR_SECURITY_WEBSOCKET_ALLOWED_ORIGINS to your front-end origin (e.g. https://app.example.com); a fully cross-origin front-end must also set LDR_SECURITY_CORS_ALLOWED_ORIGINS. Using * re-enables allow-all and is not recommended outside trusted local/dev networks.