Environment Variable Reference
All runtime behaviour is controlled through environment variables. This document is the single source of truth for every variable Briefen reads, its accepted values, and its default.
How to set variables
Docker Compose (recommended): add them to the environment: block in your compose file.
environment:
SERVER_PORT: 9000
OLLAMA_MODEL: gemma2:2b
.env file (local development): copy .env.example to .env at the repo root. Spring Boot loads it automatically on startup via spring.config.import.
cp .env.example .env
# edit .env
make dev
Shell environment: export variables before running the JAR directly.
export OLLAMA_MODEL=gemma2:2b
java -jar app.jar
Docker secrets / file-based secrets: for any variable that may contain a secret, you can append _FILE to the variable name and point it at a file containing the value. Briefen reads the file, trims whitespace, and uses the contents as the variable value. This follows the same convention used by official Docker images (PostgreSQL, MySQL, etc.).
environment:
BRIEFEN_DATASOURCE_PASSWORD_FILE: /run/secrets/db_password
BRIEFEN_OPENAI_API_KEY_FILE: /run/secrets/openai_key
Supported _FILE variables:
| Variable | File variant |
|---|---|
BRIEFEN_DATASOURCE_URL |
BRIEFEN_DATASOURCE_URL_FILE |
BRIEFEN_DATASOURCE_USERNAME |
BRIEFEN_DATASOURCE_USERNAME_FILE |
BRIEFEN_DATASOURCE_PASSWORD |
BRIEFEN_DATASOURCE_PASSWORD_FILE |
BRIEFEN_OPENAI_API_KEY |
BRIEFEN_OPENAI_API_KEY_FILE |
BRIEFEN_ANTHROPIC_API_KEY |
BRIEFEN_ANTHROPIC_API_KEY_FILE |
BRIEFEN_WEBHOOK_URL |
BRIEFEN_WEBHOOK_URL_FILE |
BRIEFEN_OIDC_CLIENT_SECRET |
BRIEFEN_OIDC_CLIENT_SECRET_FILE |
BRIEFEN_SESSION_SECRET |
BRIEFEN_SESSION_SECRET_FILE |
Setting both
VARandVAR_FILEfor the same variable is an error — the app fails fast with a clear message. The file must exist, be readable, and contain a non-empty value (after trimming whitespace).
Quick reference
Build-time only:
| Variable | Default |
|---|---|
APP_BASE_PATH |
/ |
Database
BRIEFEN_DB_TYPE
Selects the database engine. SQLite is the default and requires zero configuration. PostgreSQL is available for larger-scale or multi-instance deployments.
| Type | Enum |
| Default | sqlite |
| Value | Description |
|---|---|
sqlite |
File-based SQLite database (default). Zero setup, single-file storage. |
postgres |
PostgreSQL. Requires BRIEFEN_DATASOURCE_URL, BRIEFEN_DATASOURCE_USERNAME, and BRIEFEN_DATASOURCE_PASSWORD to be set. |
BRIEFEN_DB_TYPE: postgres
The app fails fast on startup with a clear error if an invalid value is provided, or if
postgresis selected but the required connection variables are missing.
BRIEFEN_DATASOURCE_URL
PostgreSQL JDBC connection string. Required when BRIEFEN_DB_TYPE=postgres; ignored when using SQLite.
| Type | JDBC URL string |
| Default | (none) |
| Required | When BRIEFEN_DB_TYPE=postgres |
BRIEFEN_DATASOURCE_URL: jdbc:postgresql://localhost:5432/briefen
BRIEFEN_DATASOURCE_USERNAME
PostgreSQL username. Required when BRIEFEN_DB_TYPE=postgres; ignored when using SQLite.
| Type | String |
| Default | (none) |
| Required | When BRIEFEN_DB_TYPE=postgres |
BRIEFEN_DATASOURCE_USERNAME: briefen
BRIEFEN_DATASOURCE_PASSWORD
PostgreSQL password. Required when BRIEFEN_DB_TYPE=postgres; ignored when using SQLite.
| Type | String |
| Default | (none) |
| Required | When BRIEFEN_DB_TYPE=postgres |
BRIEFEN_DATASOURCE_PASSWORD: changeme
BRIEFEN_DB_PATH
Path to the SQLite database file. The file and its parent directory are created automatically on first startup if they do not exist.
| Type | File path (string) |
| Default | ./data/briefen.db |
| Docker recommendation | Point to a path inside a named volume, e.g. /data/briefen.db |
BRIEFEN_DB_PATH: /data/briefen.db
The directory must be writable by the process. In the Docker image the default data directory is
/data, owned by thebriefenuser.
Server
SERVER_PORT
The TCP port Briefen listens on.
| Type | Integer (1–65535) |
| Default | 8080 |
SERVER_PORT: 9000
SERVER_BIND_ADDRESS
The network interface Briefen binds to. Set to 127.0.0.1 when a reverse proxy runs on the same host to prevent direct external access to the application port.
| Type | IP address string |
| Default | 0.0.0.0 (all interfaces) |
# Restrict to localhost — only the proxy can reach Briefen
SERVER_BIND_ADDRESS: 127.0.0.1
# All interfaces (default)
SERVER_BIND_ADDRESS: 0.0.0.0
When using
127.0.0.1, theports:mapping in Docker Compose should also be updated to127.0.0.1:8080:8080(or removed entirely if the proxy is in the same Docker network).
SERVER_CONTEXT_PATH
Serves the entire application (API + frontend) under a URL sub-path. Use this when Briefen shares a domain with other services and a reverse proxy does not strip the prefix before forwarding.
| Type | URL path string |
| Default | / (root — no prefix) |
| Format | Must start with /. Use a trailing slash for sub-paths: /briefen/ not /briefen. |
SERVER_CONTEXT_PATH: /briefen/
Build-time constraint. The pre-built GHCR image has
/baked into its frontend asset paths. If you setSERVER_CONTEXT_PATHto anything other than/, you must also build the image locally with the matchingAPP_BASE_PATHbuild argument:docker build --build-arg APP_BASE_PATH=/briefen/ -t briefen:local .If the proxy strips the path prefix before passing requests to Briefen (e.g.
proxy_pass http://localhost:8080/in Nginx), leaveSERVER_CONTEXT_PATHunset — the app sees all requests at/regardless.
SERVER_FORWARD_HEADERS_STRATEGY
Controls how Spring Boot processes X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host headers sent by a reverse proxy. Must be set correctly when Briefen is behind a proxy, otherwise redirects and HTTPS detection break.
| Type | Enum |
| Default | NONE |
| Value | When to use |
|---|---|
NONE |
Direct access — no reverse proxy in front of Briefen. Default. |
FRAMEWORK |
Behind a trusted reverse proxy (Nginx, Traefik, Caddy). Spring Boot reads and applies the forwarded headers. Use this for all proxied deployments. |
NATIVE |
Delegates header processing to the embedded Tomcat server rather than Spring. Rarely needed; use FRAMEWORK in most cases. |
SERVER_FORWARD_HEADERS_STRATEGY: FRAMEWORK
Always pair this with
FRAMEWORKwhen you expose Briefen via HTTPS through a proxy. Without it, Spring Boot generateshttp://redirect URLs even on an HTTPS deployment.
Networking & CORS
BRIEFEN_CORS_ALLOWED_ORIGINS
Comma-separated list of origins that are permitted to make cross-origin requests to the API. CORS is disabled entirely when this variable is empty (the default).
| Type | Comma-separated string |
| Default | (empty — CORS disabled) |
# Firefox extension only
BRIEFEN_CORS_ALLOWED_ORIGINS: moz-extension://*
# Chrome extension only
BRIEFEN_CORS_ALLOWED_ORIGINS: chrome-extension://*
# Both extensions
BRIEFEN_CORS_ALLOWED_ORIGINS: moz-extension://*,chrome-extension://*
# Extensions + local dev frontend
BRIEFEN_CORS_ALLOWED_ORIGINS: moz-extension://*,chrome-extension://*,http://localhost:5173
# Specific remote origin
BRIEFEN_CORS_ALLOWED_ORIGINS: https://briefen.example.com
When do you need this?
| Scenario | Needed? |
|---|---|
| Browser accessing Briefen on the same origin | No |
| Firefox extension connecting to a remote Briefen instance | Yes — add moz-extension://* |
| Chrome extension connecting to a remote Briefen instance | Yes — add chrome-extension://* |
| Vite dev server (port 5173) calling the backend (port 8080) | Yes — add http://localhost:5173 |
| Vite dev server accessing its own Vite proxy | No — the proxy rewrites the origin |
Ollama (local LLM)
OLLAMA_BASE_URL
The base URL of the Ollama API server.
| Type | HTTP/HTTPS URL |
| Default | http://localhost:11434 |
# Ollama as a sibling Docker Compose service (use the service name)
OLLAMA_BASE_URL: http://ollama:11434
# Ollama running on the Docker host (Mac/Windows)
OLLAMA_BASE_URL: http://host.docker.internal:11434
# Ollama running on the Docker host (Linux — replace with actual IP)
OLLAMA_BASE_URL: http://172.17.0.1:11434
# Remote Ollama server
OLLAMA_BASE_URL: http://192.168.1.100:11434
OLLAMA_MODEL
The default Ollama model used for summarization when no model is selected in the UI.
| Type | String (Ollama model tag) |
| Default | gemma3:4b |
The model must already be pulled in Ollama before it can be used. The default Docker Compose setup pulls gemma3:4b, gemma2:2b, and llama3.2:3b automatically on first start.
OLLAMA_MODEL: gemma2:2b
Recommended models by use case:
| Model | Size | Best for |
|---|---|---|
gemma2:2b |
~1.6 GB | Low-RAM devices (Raspberry Pi, small VPS) |
gemma3:4b |
~3.3 GB | Default — best quality-to-size balance, 128K context |
llama3.2:3b |
~2 GB | Alternative mid-tier option |
mistral |
~4.1 GB | Higher quality on complex articles |
llama3 |
~4.7 GB | Strong general-purpose summarization |
Users can override the model per-session from the model picker in the browser UI without any server restart.
Cloud LLM providers
BRIEFEN_OPENAI_API_KEY
OpenAI API key. When set, Briefen seeds it into the admin settings on first startup so OpenAI models appear immediately in the model picker without any UI configuration.
| Type | String (OpenAI API key — starts with sk-) |
| Default | (empty — OpenAI disabled) |
| Seeding behaviour | Written to admin settings on first startup only. Does not overwrite a key already saved in the database. Can also be set or changed later via Settings → Integrations in the browser. |
BRIEFEN_OPENAI_API_KEY: sk-...
Available OpenAI models (once key is set):
| Model | Notes |
|---|---|
gpt-4o-mini |
Fast, cost-effective — recommended for most use cases |
gpt-4o |
Higher quality |
gpt-4.1-nano |
Fastest, lowest cost |
gpt-4.1-mini |
Balanced |
o4-mini |
Reasoning model |
No data is sent to OpenAI unless the user explicitly selects an OpenAI model.
BRIEFEN_ANTHROPIC_API_KEY
Anthropic API key. Same first-startup seeding behaviour as BRIEFEN_OPENAI_API_KEY.
| Type | String (Anthropic API key — starts with sk-ant-) |
| Default | (empty — Anthropic disabled) |
| Seeding behaviour | Written to admin settings on first startup only. Does not overwrite a key already saved in the database. Can also be set or changed later via Settings → Integrations. |
BRIEFEN_ANTHROPIC_API_KEY: sk-ant-...
Available Anthropic models (once key is set):
| Model | Notes |
|---|---|
claude-haiku-4-5 |
Fastest, lowest cost — recommended for most use cases |
claude-sonnet-4-5 |
Balanced quality and speed |
claude-opus-4-5 |
Highest quality |
No data is sent to Anthropic unless the user explicitly selects a Claude model.
Webhooks
BRIEFEN_WEBHOOK_URL
HTTP(S) URL that receives a POST request whenever a summary is saved. Delivery is fire-and-forget on a virtual thread — failures are logged at WARN but never surface to the user or affect summarization.
| Type | HTTP/HTTPS URL |
| Default | (empty — webhooks disabled) |
| Priority | The URL set via Settings → Integrations in the browser takes precedence over this variable. |
| Timeout | 10s connect + 10s read |
# ntfy (self-hosted push notifications)
BRIEFEN_WEBHOOK_URL: https://ntfy.example.com/briefen
# Home Assistant
BRIEFEN_WEBHOOK_URL: https://homeassistant.local:8123/api/webhook/briefen-done
# Any HTTP endpoint
BRIEFEN_WEBHOOK_URL: https://n8n.example.com/webhook/abc123
Payload:
{
"event": "summary.completed",
"id": "3f2a1b...",
"url": "https://example.com/article",
"title": "Article Title",
"model": "gemma3:4b",
"createdAt": "2026-04-07T10:00:00Z"
}
Logging
BRIEFEN_LOG_LEVEL
Controls the log verbosity of Briefen’s own application code. Increase to DEBUG when troubleshooting summarization failures, Ollama connectivity, or unexpected API behaviour. Does not affect Spring Boot framework or third-party library log output.
| Type | Enum |
| Default | INFO |
| Value | When to use |
|---|---|
ERROR |
Only critical failures — very quiet |
WARN |
Warnings and errors only |
INFO |
Normal operation — default |
DEBUG |
Request-level detail; shows article fetching, LLM requests, webhook delivery |
TRACE |
Full trace — very verbose, avoid in production |
BRIEFEN_LOG_LEVEL: DEBUG
To increase verbosity across all code (including Spring Boot internals), use the Spring Boot native variable
LOGGING_LEVEL_ROOT=DEBUG. See Advanced / undocumented.
BRIEFEN_LOG_FORMAT
Controls the log output format. Set to json for structured JSON logs (one JSON object per line), useful for log aggregation tools like Loki, Grafana, Datadog, or simple jq filtering. When unset or any other value, Briefen uses Spring Boot’s default human-readable console format.
| Type | String |
| Default | (unset — human-readable) |
| Value | Output format |
|---|---|
| (unset) | Human-readable with timestamps, colours, and thread names — default |
json |
Structured JSON via logstash-logback-encoder. One JSON object per line with timestamp, level, logger_name, message, and stack_trace fields. |
BRIEFEN_LOG_FORMAT: json
Example JSON output:
{"timestamp":"2026-04-11T10:00:00.000+00:00","level":"INFO","logger_name":"com.briefen.service.SummaryService","message":"Returning cached summary for https://example.com/article","thread_name":"http-nio-8080-exec-1"}
Pairs well with Docker’s
json-filelog driver andjqfor ad-hoc filtering:docker logs briefen-app | jq 'select(.level == "ERROR")'
Summarization
BRIEFEN_DEFAULT_PROMPT
A custom system prompt that replaces the built-in summarization instructions for all users who have not configured a personal custom prompt in Settings → Summarization. Useful for setting a deployment-wide output language, tone, or format.
| Type | String (free text) |
| Default | (unset — built-in English summarization prompt) |
| Priority | User’s personal custom prompt (set via Settings UI) > this variable > built-in prompt |
BRIEFEN_DEFAULT_PROMPT: "You are an article summarizer. Write summaries in Spanish. Use 3-5 concise paragraphs. Start with a markdown H1 title."
The built-in prompt instructs the LLM to produce an English summary with a markdown H1 title, 3–6 paragraphs, and a Key Quotes section. Override this when you need a different language, format, or style across your entire instance.
Authentication / SSO (OpenID Connect)
Setting BRIEFEN_OIDC_ISSUER enables “Sign in with SSO” alongside password login. See OpenID Connect (SSO) for a full walkthrough, account-linking rules, and a Keycloak example.
BRIEFEN_OIDC_ISSUER
Issuer URL serving /.well-known/openid-configuration. Setting this turns on SSO.
| Type | URL |
| Default | (unset — SSO disabled) |
| Example | https://sso.example.com/realms/briefen |
BRIEFEN_OIDC_CLIENT_ID
OAuth2 client ID registered with your provider. Required when SSO is enabled.
BRIEFEN_OIDC_CLIENT_SECRET
OAuth2 client secret. Required when SSO is enabled. Supports the _FILE suffix for Docker secrets.
BRIEFEN_OIDC_REDIRECT_URL
Absolute callback URL registered at the provider. Must be https://<your-host>/login/oauth2/code/briefen.
| Type | URL |
| Default | {baseUrl}/login/oauth2/code/briefen (derived from the request) |
Behind a reverse proxy, set
SERVER_FORWARD_HEADERS_STRATEGY=FRAMEWORKso the callback URL is built with the external scheme/host.
BRIEFEN_OIDC_PROVIDER_NAME
Label shown on the sign-in button (“Sign in with <name>”). Default: SSO.
BRIEFEN_OIDC_SCOPES
Comma/space-separated scopes. openid is always included. Default: openid,profile,email.
BRIEFEN_OIDC_USERNAME_CLAIM
ID-token claim used to derive the Briefen username. Default: preferred_username.
BRIEFEN_OIDC_GROUPS_CLAIM
Claim holding the user’s group memberships. Default: groups.
BRIEFEN_OIDC_ADMIN_GROUP
When set, membership in this group grants admin — synced on every login. When unset, roles are never changed from group claims. Default: (unset).
BRIEFEN_OIDC_ALLOW_SIGNUP
Auto-create a Briefen account on first SSO login. Default: true.
BRIEFEN_OIDC_LINK_BY_EMAIL
Link an SSO identity to an existing account by verified email. Default: true.
BRIEFEN_OIDC_LINK_BY_USERNAME
Link an SSO identity to an existing account by username. Default: true.
BRIEFEN_DISABLE_PASSWORD_LOGIN
SSO-only mode: hide and reject password login. Ignored unless SSO is configured (so you can never lock everyone out). Default: false.
BRIEFEN_SESSION_TTL
Lifetime of the bearer-token session issued after an SSO login (Spring Duration, e.g. 30d, 12h). Default: 30d.
BRIEFEN_API_TOKEN_TTL
Lifetime of a personal access token (created in Settings → Access tokens for browser extensions / headless clients). Spring Duration. Default: 3650d (~10 years).
BRIEFEN_RATE_LIMIT_ENABLED
Enable per-IP rate limiting on the OIDC handshake (/oauth2/authorization/**, /login/oauth2/code/**) and first-run setup (/api/setup). Default: true.
BRIEFEN_RATE_LIMIT_MAX_REQUESTS
Max requests allowed per IP per window for the rate-limited endpoints. Default: 30.
BRIEFEN_RATE_LIMIT_WINDOW
The rate-limit window (Spring Duration). Default: 60s.
BRIEFEN_SESSION_SECRET
HMAC key protecting the short-lived OIDC handshake cookie. Optional — a random per-instance key is generated when unset (a restart mid-login just makes the user click “Sign in” again). Set a stable value for multi-instance deployments. Supports the _FILE suffix.
BRIEFEN_SECURE_COOKIES
Mark the OIDC handshake cookie Secure (send only over HTTPS). Set true in production behind TLS. Default: false.
Build-time variables
These are Docker build arguments (ARG), not runtime environment variables. They are consumed during docker build and baked into the image — they cannot be changed at runtime.
APP_BASE_PATH
The URL base path baked into the compiled frontend assets. Must match SERVER_CONTEXT_PATH exactly.
| Type | URL path string |
| Default | / |
| Set during | docker build --build-arg APP_BASE_PATH=<value> |
| Affects | Vite’s base option — asset src and href paths in the compiled HTML |
# Root deployment (default — pre-built GHCR image always uses this)
docker build -t briefen:local .
# Sub-path deployment
docker build --build-arg APP_BASE_PATH=/briefen/ -t briefen:local .
The pre-built image on GHCR always uses
APP_BASE_PATH=/. If you need a custom sub-path, build the image locally.
Advanced / undocumented
These variables are not exposed in .env.example but are accessible through Spring Boot’s relaxed binding — any Spring property can be set via an environment variable by uppercasing it and replacing . and - with _.
ARTICLE_FETCH_TIMEOUT
Maximum time Briefen waits for an article page to respond before giving up. Increase if you regularly summarize sites with slow servers.
| Type | Duration string (10s, 30s, 1m) |
| Default | 10s |
| Spring property | article.fetch-timeout |
ARTICLE_FETCH_TIMEOUT: 30s
LOGGING_LEVEL_COM_BRIEFEN
Spring Boot’s native relaxed-binding equivalent of BRIEFEN_LOG_LEVEL. Both variables set the same underlying property (logging.level.com.briefen). Prefer BRIEFEN_LOG_LEVEL — it follows the project’s naming convention.
# Prefer this:
BRIEFEN_LOG_LEVEL: DEBUG
# Equivalent (Spring Boot relaxed binding):
LOGGING_LEVEL_COM_BRIEFEN: DEBUG
LOGGING_LEVEL_ROOT
Controls the log verbosity of all code including Spring Boot and third-party libraries. Only raise this temporarily for deep debugging.
| Type | Enum (same values as above) |
| Default | INFO |
| Spring property | logging.level.root |
LOGGING_LEVEL_ROOT: DEBUG
Variable interactions
Some variables interact with each other in non-obvious ways:
| If you set… | You must also… |
|---|---|
BRIEFEN_DB_TYPE=postgres |
Set BRIEFEN_DATASOURCE_URL, BRIEFEN_DATASOURCE_USERNAME, and BRIEFEN_DATASOURCE_PASSWORD |
SERVER_CONTEXT_PATH=/briefen/ |
Build the image locally with --build-arg APP_BASE_PATH=/briefen/ |
SERVER_BIND_ADDRESS=127.0.0.1 |
Ensure the reverse proxy connects to 127.0.0.1:8080, not via a Docker network alias |
SERVER_FORWARD_HEADERS_STRATEGY=FRAMEWORK |
Ensure your reverse proxy sends X-Forwarded-Proto and X-Forwarded-Host headers |
BRIEFEN_CORS_ALLOWED_ORIGINS including moz-extension://* |
Use the Firefox extension with a remote Briefen instance |
OLLAMA_MODEL (non-default model) |
Ensure that model is pulled in Ollama — it is not auto-pulled for custom values |