Configuration
All configuration is done through environment variables. The defaults are suitable for most setups.
Server
| Variable | Default | Description |
|---|---|---|
PORT | 3000 | Port the server listens on |
HOST | 0.0.0.0 | Bind address |
DATABASE_URL | /app/data/cornerstone.db | Path to the SQLite database file |
LOG_LEVEL | info | Log verbosity (trace, debug, info, warn, error, fatal) |
NODE_ENV | production | Environment mode |
Sessions
| Variable | Default | Description |
|---|---|---|
SESSION_DURATION | 604800 | Session lifetime in seconds (default: 7 days) |
SECURE_COOKIES | true | Send cookies with Secure flag (requires HTTPS) |
SECURE_COOKIES defaults to true, which means cookies are only sent over HTTPS. If you are testing locally without HTTPS, set this to false. Behind a reverse proxy with TLS termination, keep the default true.
Reverse Proxy
| Variable | Default | Description |
|---|---|---|
TRUST_PROXY | false | Set to true when running behind a reverse proxy (nginx, Caddy, Traefik, etc.). Only the first proxy hop is trusted, and rate limiting uses a resilient client identifier that resists X-Forwarded-For spoofing. |
EXTERNAL_URL | -- | Public-facing base URL (e.g., https://myhouse.example.com). Used for OIDC callback, CalDAV/CardDAV discovery, and .mobileconfig generation. |
When deploying behind a reverse proxy, set TRUST_PROXY=true so the server correctly reads forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc.). Set EXTERNAL_URL to the public URL users access your instance at -- this ensures OIDC callbacks, CalDAV/CardDAV discovery, and Apple configuration profiles work correctly regardless of internal networking.
OIDC (Single Sign-On)
OIDC is automatically enabled when OIDC_ISSUER, OIDC_CLIENT_ID, and OIDC_CLIENT_SECRET are all set. No separate "enable" flag is needed.
| Variable | Default | Description |
|---|---|---|
OIDC_ISSUER | -- | Your OIDC provider's issuer URL (e.g., https://auth.example.com/realms/main) |
OIDC_CLIENT_ID | -- | Client ID registered with your OIDC provider |
OIDC_CLIENT_SECRET | -- | Client secret for the OIDC client |
The OIDC callback URL is automatically derived as <EXTERNAL_URL>/api/auth/oidc/callback. If EXTERNAL_URL is not set, it falls back to the request's protocol and host. See OIDC Setup for details on registering this URL with your identity provider.
Localization
| Variable | Default | Description |
|---|---|---|
CURRENCY | EUR | ISO 4217 currency code (e.g., EUR, USD, CHF) used for formatting monetary values |
Diary
| Variable | Default | Description |
|---|---|---|
DIARY_AUTO_EVENTS | true | Whether the construction diary automatically logs system events (status changes, invoice updates, etc.). Set to false to disable automatic entries. |
DIARY_DRAFT_RETENTION_DAYS | 30 | Days a draft diary entry can sit untouched before the daily orphan cleanup deletes it. Set to 0 to disable the cleanup and keep drafts forever. |
PHOTO_STORAGE_PATH | <data-dir>/photos | Directory where diary photos are stored (both originals and annotated copies). Defaults to a photos folder next to the database file. |
PHOTO_MAX_FILE_SIZE_MB | 20 | Maximum file size in megabytes for photo uploads |
PHOTO_STORAGE_PATH defaults to a photos directory alongside your database file. If you use a custom DATABASE_URL, the photo directory is created relative to it. Make sure the path is within a persistent Docker volume so photos survive container restarts.
Backups
| Variable | Default | Description |
|---|---|---|
BACKUP_DIR | /backups | Directory where backup archives are written. Must be outside the app data directory. |
BACKUP_CADENCE | -- | Cron expression for automatic scheduled backups (e.g., 0 2 * * * for daily at 2 AM). If unset, only manual backups are available. |
BACKUP_RETENTION | -- | Maximum number of backup archives to keep. The oldest archives are deleted when the limit is exceeded. If unset, backups are kept indefinitely. |
The backup feature is enabled whenever BACKUP_DIR resolves to a directory outside the app data directory -- which is true by default. See Backups for setup, scheduling, and restore instructions.
Paperless-ngx (Document Integration)
The document integration is automatically enabled when both PAPERLESS_URL and PAPERLESS_API_TOKEN are set.
| Variable | Default | Description |
|---|---|---|
PAPERLESS_URL | -- | Base URL of your Paperless-ngx instance used by the server for API calls (e.g., http://paperless:8000 in Docker) |
PAPERLESS_API_TOKEN | -- | API authentication token from Paperless-ngx |
PAPERLESS_EXTERNAL_URL | -- | Browser-facing URL for Paperless-ngx links (e.g., https://paperless.example.com). If unset, falls back to PAPERLESS_URL. |
PAPERLESS_FILTER_TAG | -- | Optional tag name. When set, only Paperless-ngx documents tagged with this name are visible to Cornerstone. Useful for keeping personal documents private when sharing a Paperless-ngx instance across applications. |
For detailed setup instructions, see Documents Setup.
Auto-itemize Invoices (LLM)
The auto-itemize feature reads line items off invoice PDFs (via Paperless OCR) and proposes budget lines using any OpenAI-compatible LLM provider. It is disabled by default -- set all three required variables to enable it.
| Variable | Default | Description |
|---|---|---|
LLM_BASE_URL | -- | Base URL of the LLM API (e.g., https://api.openai.com/v1, https://generativelanguage.googleapis.com/v1beta/openai) |
LLM_API_KEY | -- | Bearer token / API key for the LLM provider |
LLM_MODEL | -- | Model identifier (e.g., gpt-4o-mini, gemini-2.5-flash, claude-haiku-4-5-20251001) |
LLM_REQUEST_TIMEOUT_MS | 30000 | Request timeout in milliseconds |
LLM_MAX_TOKENS | 16384 | Max output tokens per call. The default handles 100+ line invoices; increase if you see LLM_INVALID_RESPONSE errors with finishReason="length". |
LLM_PROVIDER | -- | One of openai, anthropic, gemini, ollama, or generic. Auto-detected from LLM_BASE_URL when unset; override only if auto-detection misses your provider. |
When all three required variables are set, the Auto-itemize button appears on invoice detail pages that have at least one Paperless document linked. See Auto-itemize Invoices for the full guide, provider examples, and what data leaves your host.