Environment Variables
This page is the source-of-truth reference for OpenReader environment variables.
Use Settings → Admin as the primary source of truth for shared providers and runtime site features.
API_BASE / API_KEY are optional one-time provider bootstrap seeds.
Runtime site features are seeded with RUNTIME_SEED_JSON / RUNTIME_SEED_JSON_PATH.
Quick Reference Table
| Variable | Area | Default | When to set |
|---|---|---|---|
LOG_FORMAT | Runtime logging | pretty | Set json for structured logs |
LOG_LEVEL | Runtime logging | info | Set app server log level |
API_BASE | TTS provider bootstrap seed | unset | Optional first-boot base URL for default-openai |
API_KEY | TTS provider bootstrap seed | unset | Optional first-boot API key for default-openai |
BASE_URL | Auth | unset | Required at startup |
AUTH_SECRET | Auth | unset | Required at startup |
AUTH_TRUSTED_ORIGINS | Auth | empty | Add extra allowed origins |
USE_ANONYMOUS_AUTH_SESSIONS | Auth | false | Set true to allow anonymous auth sessions |
GITHUB_CLIENT_ID | Auth/OAuth | unset | Set with GITHUB_CLIENT_SECRET to enable GitHub sign-in |
GITHUB_CLIENT_SECRET | Auth/OAuth | unset | Set with GITHUB_CLIENT_ID to enable GitHub sign-in |
ADMIN_EMAILS | Admin | empty | Comma-separated emails auto-promoted to admin |
POSTGRES_URL | Database | unset (SQLite mode) | Set to switch metadata/auth DB to Postgres |
USE_EMBEDDED_WEED_MINI | Storage | true when unset | Set false to use external S3-compatible storage only |
WEED_MINI_DIR | Storage | docstore/seaweedfs | Override embedded SeaweedFS data directory |
WEED_MINI_WAIT_SEC | Storage | 20 | Tune SeaweedFS startup wait timeout |
S3_ACCESS_KEY_ID | Storage | auto-generated in embedded mode | Set explicitly for stable/external credentials |
S3_SECRET_ACCESS_KEY | Storage | auto-generated in embedded mode | Set explicitly for stable/external credentials |
S3_BUCKET | Storage | openreader-documents in embedded mode | Required for external S3-compatible storage |
S3_REGION | Storage | us-east-1 in embedded mode | Required for external S3-compatible storage |
S3_ENDPOINT | Storage | derived in embedded mode | Set for S3-compatible providers (MinIO/SeaweedFS/R2/etc.) |
S3_FORCE_PATH_STYLE | Storage | true in embedded mode | Set per provider requirement |
S3_PREFIX | Storage | openreader | Customize object key prefix |
IMPORT_LIBRARY_DIR | Library import | docstore/library fallback | Set a single server library root |
IMPORT_LIBRARY_DIRS | Library import | unset | Set multiple roots (comma/colon/semicolon separated) |
EMBEDDED_COMPUTE_WORKER_PORT | Compute | 8081 | Override embedded worker bind port |
EMBEDDED_NATS_PORT | Compute | 4222 | Override embedded NATS client port |
EMBEDDED_NATS_MONITOR_PORT | Compute | 8222 | Override embedded NATS monitor port |
EMBEDDED_NATS_STORE_DIR | Compute | docstore/nats/jetstream | Override embedded JetStream storage directory |
NATS_URL | Compute | nats://127.0.0.1:4222 in embedded startup | Override embedded startup or set standalone worker URL |
COMPUTE_LOG_LEVEL | Compute | info | Compute worker log level |
COMPUTE_JOB_CONCURRENCY | Compute | 1 | Shared compute concurrency cap |
COMPUTE_WHISPER_TIMEOUT_MS | Compute | 30000 | Whisper alignment timeout budget |
COMPUTE_PDF_TIMEOUT_MS | Compute | 300000 | PDF parse timeout budget |
COMPUTE_OP_STALE_MS | Compute | max(30m, 4x max compute timeout) | Shared stale window for compute op replacement |
WHISPER_MODEL_BASE_URL | Compute model source | onnx-community default | Override Whisper ONNX model base URL |
PDF_LAYOUT_MODEL_BASE_URL | Compute model source | PP-DocLayoutV3 default | Override PDF layout ONNX model base URL |
COMPUTE_WORKER_URL | External compute mode | unset | Set only for standalone external worker mode |
COMPUTE_WORKER_TOKEN | External compute mode | unset | Required for standalone external worker auth |
FFMPEG_BIN | Audio runtime | auto-detected (ffmpeg-static) | Override ffmpeg binary path |
DISABLE_AUTH_RATE_LIMIT | Auth request throttling | false | Set true to disable Better Auth request rate limiting |
ENABLE_TEST_NAMESPACE | Testing/CI | unset | Honor x-openreader-test-namespace header in production builds |
RUN_DRIZZLE_MIGRATIONS | DB migrations | true | Set false to skip startup Drizzle migrations |
RUN_FS_MIGRATIONS | Storage migrations | true | Set false to skip startup filesystem -> S3/DB migration pass |
RUNTIME_SEED_JSON_PATH | Runtime JSON seed | unset | Absolute path to first-boot JSON seed document |
RUNTIME_SEED_JSON | Runtime JSON seed | unset | Inline first-boot JSON seed document |
Runtime Logging
LOG_FORMAT
Controls log output format for server-side Pino loggers.
- Default:
pretty - Allowed values:
pretty,json - Applies to app server and compute worker
LOG_LEVEL
App server log level.
- Default:
info
TTS Provider and Request Behavior
API_BASE
Optional first-boot bootstrap base URL for the auto-created default-openai shared provider.
- Example:
http://host.docker.internal:8880/v1 - Read only for provider bootstrap when shared providers are empty and
API_KEYis set. - After bootstrap, provider configuration is DB-backed and managed in Settings → Admin → Shared providers.
API_KEY
Optional first-boot bootstrap API key for the auto-created default-openai shared provider.
- Read only for provider bootstrap when shared providers are empty.
- Stored encrypted at rest after bootstrap.
- After bootstrap, provider configuration is DB-backed and managed in Settings → Admin → Shared providers.
TTS Daily Rate Limiting (Runtime Settings)
Managed as runtime config in Settings → Admin → Site features.
disableTtsRateLimitdefault:true(daily TTS limits disabled)ttsDailyLimitAnonymousdefault:50000ttsDailyLimitAuthenticateddefault:500000ttsIpDailyLimitAnonymousdefault:100000ttsIpDailyLimitAuthenticateddefault:1000000
TTS Upstream Settings (Runtime Settings)
Managed as runtime config in Settings → Admin → Site features → TTS upstream.
ttsUpstreamMaxRetriesdefault:2ttsUpstreamTimeoutMsdefault:285000ttsCacheMaxSizeBytesdefault:268435456(256 MB)ttsCacheTtlMsdefault:1800000(30 minutes)
There are no dedicated env vars for these runtime settings.
Auth and Identity
BASE_URL
Required external base URL for this OpenReader instance.
- Required at startup
- Example:
http://localhost:3003orhttps://reader.example.com
AUTH_SECRET
Required secret key used by auth/session handling.
- Required at startup
- Generate with
openssl rand -hex 32
AUTH_TRUSTED_ORIGINS
Additional allowed origins for auth requests.
- Comma-separated list
BASE_URLorigin is trusted automatically
USE_ANONYMOUS_AUTH_SESSIONS
Controls whether auth-enabled deployments can create/use anonymous sessions.
- Default:
false
GITHUB_CLIENT_ID
GitHub OAuth client ID.
- Set with
GITHUB_CLIENT_SECRET
GITHUB_CLIENT_SECRET
GitHub OAuth client secret.
- Set with
GITHUB_CLIENT_ID
ADMIN_EMAILS
Comma-separated list of email addresses auto-promoted to admin.
- Requires auth to be enabled
- Admins can manage shared providers and runtime site features in-app
Database and Object Blob Storage
POSTGRES_URL
Switches metadata/auth storage from SQLite to Postgres.
- Unset: SQLite at
docstore/sqlite3.db - Set: Postgres mode
USE_EMBEDDED_WEED_MINI
Controls embedded SeaweedFS startup.
- Default behavior: treated as enabled when unset
- Set
falseto rely on external S3-compatible storage
WEED_MINI_DIR
Data directory for embedded SeaweedFS (weed mini).
- Default:
docstore/seaweedfs
WEED_MINI_WAIT_SEC
Max wait time for embedded SeaweedFS startup.
- Default:
20
S3_ACCESS_KEY_ID
S3 access key.
- Optional in embedded mode (auto-generated when unset)
- Required for external S3 mode
S3_SECRET_ACCESS_KEY
S3 secret key.
- Optional in embedded mode (auto-generated when unset)
- Required for external S3 mode
S3_BUCKET
S3 bucket name.
- Embedded default:
openreader-documents - Required for external S3 mode
S3_REGION
S3 region.
- Embedded default:
us-east-1 - Required for external S3 mode
S3_ENDPOINT
Custom endpoint for S3-compatible providers.
- Optional for AWS
- Typical for MinIO/SeaweedFS/R2
S3_FORCE_PATH_STYLE
Force path-style S3 URLs.
- Embedded default:
true
S3_PREFIX
Object key prefix.
- Default:
openreader
Library Import
IMPORT_LIBRARY_DIR
Single library source directory.
IMPORT_LIBRARY_DIRS
Multiple library roots.
- Supports comma, colon, or semicolon-separated values
Compute Worker and Model Configuration
EMBEDDED_COMPUTE_WORKER_PORT
Embedded compute worker port.
- Default:
8081
EMBEDDED_NATS_PORT
Embedded NATS client port.
- Default:
4222
EMBEDDED_NATS_MONITOR_PORT
Embedded NATS monitor port.
- Default:
8222
EMBEDDED_NATS_STORE_DIR
Embedded NATS JetStream data directory.
- Default:
docstore/nats/jetstream
NATS_URL
NATS URL used by compute services.
- Embedded startup default:
nats://127.0.0.1:4222
COMPUTE_LOG_LEVEL
Compute worker log level.
- Default:
info
COMPUTE_JOB_CONCURRENCY
Max concurrent compute jobs per worker.
- Default:
1
COMPUTE_WHISPER_TIMEOUT_MS
Whisper alignment timeout budget.
- Default:
30000
COMPUTE_PDF_TIMEOUT_MS
PDF parse timeout budget.
- Default:
300000
COMPUTE_OP_STALE_MS
Stale operation window before worker/app cleanup logic can replace an op.
- Default:
max(30m, 4x max compute timeout)
WHISPER_MODEL_BASE_URL
Base URL for Whisper ONNX model downloads.
PDF_LAYOUT_MODEL_BASE_URL
Base URL for PDF layout model downloads.
COMPUTE_WORKER_URL
External compute worker URL.
- Leave unset for embedded worker mode
COMPUTE_WORKER_TOKEN
Shared token for app-to-external-worker requests.
Compute PDF Parsing Rate Limiting (Runtime Settings)
Managed as runtime config in Settings → Admin → Site features.
disableComputeRateLimitdefault:truecomputeParseBurstMaxdefault:8computeParseBurstWindowSecdefault:60computeParseSustainedMaxdefault:24computeParseSustainedWindowSecdefault:600maxUploadMbdefault:200
There are no dedicated env vars for these runtime settings.
Audio Runtime
FFMPEG_BIN
Override ffmpeg binary path used for audio processing.
- Used by audiobook processing routes and compute worker Whisper audio decode.
Testing and CI
DISABLE_AUTH_RATE_LIMIT
Disables Better Auth request rate limiting.
- Default:
false
ENABLE_TEST_NAMESPACE
Enables the x-openreader-test-namespace header path in production builds.
Migration Controls
RUN_DRIZZLE_MIGRATIONS
Controls startup Drizzle schema migrations.
- Default:
true - Set
falseto skip startup migration run
RUN_FS_MIGRATIONS
Controls startup filesystem-to-S3/DB migration pass.
- Default:
true - Set
falseto skip startup storage migration run
Runtime JSON Seed (v4)
RUNTIME_SEED_JSON_PATH
Path-based first-boot seed document.
- If both
RUNTIME_SEED_JSON_PATHandRUNTIME_SEED_JSONare set, path wins. - Value must point to a JSON file readable by the app process.
RUNTIME_SEED_JSON
Inline first-boot seed document.
- Used only when
RUNTIME_SEED_JSON_PATHis unset. - Must be a JSON object with
version: 1.
Supported top-level keys:
version(required, must be1)runtimeConfig(optional object, strict-validated against runtime schema)providers(optional array of shared provider seed entries)
Example:
{
"version": 1,
"runtimeConfig": {
"enableUserSignups": true,
"restrictUserApiKeys": true,
"defaultTtsProvider": "custom-openai",
"enableTtsProvidersTab": true,
"enableAudiobookExport": true,
"enableDocxConversion": true,
"enableDestructiveDeleteActions": true,
"showAllProviderModels": true,
"disableTtsRateLimit": true,
"ttsDailyLimitAnonymous": 50000,
"ttsDailyLimitAuthenticated": 500000,
"ttsIpDailyLimitAnonymous": 100000,
"ttsIpDailyLimitAuthenticated": 1000000,
"ttsCacheMaxSizeBytes": 268435456,
"ttsCacheTtlMs": 1800000,
"ttsUpstreamMaxRetries": 2,
"ttsUpstreamTimeoutMs": 285000,
"disableComputeRateLimit": true,
"computeParseBurstMax": 8,
"computeParseBurstWindowSec": 60,
"computeParseSustainedMax": 24,
"computeParseSustainedWindowSec": 600,
"maxUploadMb": 200,
"changelogFeedUrl": "https://docs.openreader.richardr.dev/changelog/manifest.json"
},
"providers": [
{
"slug": "default-openai",
"displayName": "Default (seeded)",
"providerType": "custom-openai",
"baseUrl": "http://localhost:8880/v1",
"apiKey": "api_key_optional",
"defaultModel": "kokoro",
"enabled": true
}
]
}
Provider fallback behavior:
- If the JSON seed includes
providers(including an empty array),API_BASE/API_KEYfallback is skipped. - If the JSON seed does not include a
providerskey, the legacyAPI_BASE/API_KEYbootstrap fallback can still createdefault-openaiwhen provider rows are empty.
Precedence summary:
- Runtime reads: admin DB runtime rows override built-in defaults.
- Seed input (
RUNTIME_SEED_JSON*) only populates missing runtime rows on first boot; it does not overwrite existing/admin-edited rows. - Provider bootstrap order: JSON
providerssection >API_BASE/API_KEYfallback > no provider bootstrap.