Eliminate the enableDestructiveDeleteActions feature flag from runtime configuration, admin panel, environment docs, and user settings modal. Remove all references, toggles, and documentation for this flag. This simplifies the runtime config and user interface by consolidating destructive actions under account deletion only. BREAKING CHANGE: The enableDestructiveDeleteActions runtime flag is no longer supported. Any configuration or code depending on this flag must be updated.
465 lines
14 KiB
Markdown
465 lines
14 KiB
Markdown
---
|
|
title: Environment Variables
|
|
toc_max_heading_level: 3
|
|
---
|
|
|
|
This page is the source-of-truth reference for OpenReader environment variables.
|
|
|
|
:::note Recommended configuration path
|
|
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_KEY` is 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**.
|
|
|
|
- `disableTtsRateLimit` default: `true` (daily TTS limits disabled)
|
|
- `ttsDailyLimitAnonymous` default: `50000`
|
|
- `ttsDailyLimitAuthenticated` default: `500000`
|
|
- `ttsIpDailyLimitAnonymous` default: `100000`
|
|
- `ttsIpDailyLimitAuthenticated` default: `1000000`
|
|
|
|
### TTS Upstream Settings (Runtime Settings)
|
|
|
|
Managed as runtime config in **Settings → Admin → Site features → TTS upstream**.
|
|
|
|
- `ttsUpstreamMaxRetries` default: `2`
|
|
- `ttsUpstreamTimeoutMs` default: `285000`
|
|
- `ttsCacheMaxSizeBytes` default: `268435456` (256 MB)
|
|
- `ttsCacheTtlMs` default: `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:3003` or `https://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_URL` origin 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 `false` to 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**.
|
|
|
|
- `disableComputeRateLimit` default: `true`
|
|
- `computeParseBurstMax` default: `8`
|
|
- `computeParseBurstWindowSec` default: `60`
|
|
- `computeParseSustainedMax` default: `24`
|
|
- `computeParseSustainedWindowSec` default: `600`
|
|
- `maxUploadMb` default: `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 `false` to skip startup migration run
|
|
|
|
### RUN_FS_MIGRATIONS
|
|
|
|
Controls startup filesystem-to-S3/DB migration pass.
|
|
|
|
- Default: `true`
|
|
- Set `false` to skip startup storage migration run
|
|
|
|
## Runtime JSON Seed (v4)
|
|
|
|
### RUNTIME_SEED_JSON_PATH
|
|
|
|
Path-based first-boot seed document.
|
|
|
|
- If both `RUNTIME_SEED_JSON_PATH` and `RUNTIME_SEED_JSON` are 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_PATH` is unset.
|
|
- Must be a JSON object with `version: 1`.
|
|
|
|
Supported top-level keys:
|
|
|
|
- `version` (required, must be `1`)
|
|
- `runtimeConfig` (optional object, strict-validated against runtime schema)
|
|
- `providers` (optional array of shared provider seed entries)
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"version": 1,
|
|
"runtimeConfig": {
|
|
"enableUserSignups": true,
|
|
"restrictUserApiKeys": true,
|
|
"defaultTtsProvider": "custom-openai",
|
|
"enableTtsProvidersTab": true,
|
|
"enableAudiobookExport": true,
|
|
"enableDocxConversion": 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_KEY` fallback is skipped.
|
|
- If the JSON seed does not include a `providers` key, the legacy `API_BASE` / `API_KEY` bootstrap fallback can still create `default-openai` when 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 `providers` section > `API_BASE`/`API_KEY` fallback > no provider bootstrap.
|
|
|
|
## Related
|
|
|
|
- [Admin Panel](../configure/admin-panel)
|
|
- [TTS Providers](../configure/tts-providers)
|
|
- [Local Development](../deploy/local-development)
|
|
- [Vercel Deployment](../deploy/vercel-deployment)
|