Skip to content

Configuration

Rod Christiansen edited this page Oct 8, 2026 · 3 revisions

Configuration

Every environment variable the code at HEAD actually reads, found by grepping process.env. Variables that appear only in .env.example or docker-compose.yml and are never read by application code are listed at the bottom so you do not go looking for their effect.

NEXT_PUBLIC_-prefixed variables are inlined into the client bundle at build time. In a container image that means they are fixed when the image is built, not when it starts. Everything else is read at runtime on the server.

Core

Variable Default Required Effect
API_BASE_URL none Yes Base URL of reportmate-api. Every proxy route returns 500 without it, and the middleware skips device-identifier resolution
API_INTERNAL_SECRET none In production Sent upstream as X-Internal-Secret. First choice of credential
REPORTMATE_PASSPHRASE none No Sent upstream as X-API-PASSPHRASE when API_INTERNAL_SECRET is unset. Intended as a local-development fallback
NODE_ENV set by Next.js No development enables the localhost auth bypass and disables secure cookies and the service worker
PORT 3000 No Reported by /api/diagnostic; the Docker image sets it for the server

Authentication

Variable Default Required Effect
NEXTAUTH_SECRET none Yes Signs and verifies session JWTs. Without it the middleware cannot read a session and kiosk sessions return 500
NEXTAUTH_URL none In production Canonical base URL. Used to rewrite OAuth callbacks and every auth redirect
NEXT_PUBLIC_SITE_URL none No Fallback for NEXTAUTH_URL everywhere it is read
AUTH_PROVIDERS azure-ad No Comma-separated list from azure-ad, google, credentials
DEFAULT_AUTH_PROVIDER azure-ad No Recorded in the auth config object. The automatic sign-in path calls azure-ad directly regardless
ALLOWED_DOMAINS empty No Comma-separated email domains permitted to sign in. Empty permits every domain
REQUIRE_EMAIL_VERIFICATION false No When true, a Google sign-in is refused unless the profile reports a verified email. Has no effect on the Entra ID provider
AZURE_AD_CLIENT_ID none With azure-ad Application (client) id
AZURE_AD_CLIENT_SECRET none With azure-ad Client secret
AZURE_AD_TENANT_ID none With azure-ad Directory (tenant) id
AZURE_AD_SCOPE openid profile email User.Read No Scopes requested at authorization
GOOGLE_CLIENT_ID none With google OAuth client id
GOOGLE_CLIENT_SECRET none With google OAuth client secret
KIOSK_TOKENS empty No Comma-separated label:token or bare token entries for read-only wall displays. Entries shorter than 16 characters are ignored

Missing any of the three AZURE_AD_* values while azure-ad is in AUTH_PROVIDERS throws at module load, which surfaces as every auth route failing rather than as a sign-in error.

Behaviour flags

Variable Default Required Effect
NEXT_PUBLIC_DEMO_MODE false No true disables authentication in the middleware for the whole app and puts Settings into a read-only subset with destructive actions hidden
NEXT_PUBLIC_ENABLE_SIGNALR unset (the Dockerfile's ENABLE_SIGNALR build argument defaults to true) No The dashboard opens the live stream unless this is exactly "false". The unused hook in app/dashboard/hooks.ts and the SignalRStatus component take the opposite reading and require "true", so set it to true to satisfy both
NEXT_PUBLIC_VERBOSE_DEBUG false No true turns on verbose output from src/lib/debug-logger.ts
NEXT_PUBLIC_API_BASE_URL none No Fallback base URL for the device page's server-side metadata fetch when API_BASE_URL is unset
NEXT_PUBLIC_SUPPORT_EMAIL none No Renders a support mailto link on the sign-in error page
NEXT_PUBLIC_APP_VERSION 1.0.0 No Version the dynamic module loader compares against

Build and version metadata

/api/version reads these in order and reports the first that is set. The Dockerfile passes the first group in as build arguments.

Variable Reported as
CONTAINER_IMAGE_TAG, NEXT_PUBLIC_VERSION, VERSION, DOCKER_TAG version
BUILD_ID, NEXT_PUBLIC_BUILD_ID, GITHUB_SHA build id, else .next/BUILD_ID
BUILD_TIME, NEXT_PUBLIC_BUILD_TIME build time, else the current time
CONTAINER_IMAGE_TAG, IMAGE_TAG, DOCKER_IMAGE_TAG image tag
CONTAINER_REGISTRY qualifies a datestamped tag into a full image reference; the tag is reported bare when unset

Testing

Variable Default Effect
TEST_ENV unset production or staging points Playwright at a remote base URL and skips starting a dev server
E2E_BASE_URL http://localhost:3000 Base URL when TEST_ENV=production
TEST_DEVICE_SERIAL TESTSERIAL0001 Serial the end-to-end specs use for device routes
CI unset Enables retries, single worker, and forbidOnly
API_BASE_URL, API_INTERNAL_SECRET, REPORTMATE_PASSPHRASE none The api-health project calls reportmate-api directly with these and fails to load without API_BASE_URL

Read but inert

These are read by code that does nothing with the value. Setting them changes nothing at HEAD.

Variable Where
AZURE_CLIENT_ID, MSI_CLIENT_ID Assigned to an unused local in app/api/device/route.ts
AUTH_TRUST_HOST Only echoed by /api/test-auth
VERCEL_URL Used to build a self-referential base URL in src/lib/deviceResolver.ts, which only matters on Vercel
HOME Path heuristic in a launchd table component

Present in examples, not read by the app

.env.example, .env.local.example and docker-compose.yml carry variables that belong to other services. NEXT_PUBLIC_WPS_URL is passed through the Dockerfile and docker-compose.yml, but no application code reads it — the stream URL comes from /api/v1/negotiate. DATABASE_URL, DB_PASSWORD, CLIENT_PASSPHRASES, AZURE_STORAGE_CONNECTION_STRING, QUEUE_NAME and EVENTS_CONNECTION belong to the API and database services, not to the dashboard.

Clone this wiki locally