Skip to main content

Environment variables

All variables are validated at startup by the backend (@nestjs/config + Joi). Credentials are never committed — only the shape is documented here.

Backend (shell-backend)​

VariableRequiredDescription
DATABASE_URLyesPostgreSQL connection string
REDIS_URLyesRedis connection string
FIREBASE_PROJECT_IDyes in practiceFirebase project id. Without a service-account cert this is what the Admin SDK is initialised with; with neither, every verifyIdToken fails and all authenticated routes answer 401
FIREBASE_CLIENT_EMAIL—Admin SDK service account email
FIREBASE_PRIVATE_KEY—Admin SDK private key (PEM)
SENTRY_DSN—Self-hosted Sentry DSN; init is skipped when absent. Must be a real DSN (scheme://publicKey@host/projectId) — passing the ingest endpoint URL instead is rejected with Invalid Sentry Dsn and nothing is reported
SENTRY_ENVIRONMENT—production / staging / development
PORT—HTTP port (default 3000)
CORS_ORIGIN—Allowed origin(s), comma-separated
AUDIT_WORKER_ENABLED—true to run the BullMQ worker in-pod
SWAGGER_ENABLED—Serves /api + /api-json as one unit. Unset => on unless NODE_ENV is production/staging
REDIS_HOST / REDIS_PORT—Alternative to REDIS_URL; used only when REDIS_URL is unset
FIREBASE_AUTH_EMULATOR_HOST—Read by firebase-admin itself; e.g. 127.0.0.1:9099
OTEL_EXPORTER_OTLP_ENDPOINT—Enables OpenTelemetry tracing when set
S3_ENDPOINT—S3-compatible object storage endpoint (MinIO locally, DigitalOcean Spaces in cloud)
S3_BUCKET—Object storage bucket name
S3_ACCESS_KEY—Object storage access key id
S3_SECRET_KEY—Object storage secret access key
SMTP_HOST—Outbound SMTP host (Mailpit locally, SendGrid SMTP in cloud)
SMTP_PORT—Outbound SMTP port (1025 for Mailpit)
SENDGRID_API_BASE_URL—Base URL of the SendGrid HTTP API (WireMock on :9090 locally)
SENDGRID_API_KEY—SendGrid API key with Mail Send permission

REDIS_URL accepts rediss:// for a TLS endpoint; the scheme is what switches the client into TLS mode.

Frontend (shell-frontend, VITE_-prefixed)​

VariableDescription
VITE_API_BASE_URLShell API base URL (default http://localhost:3000)
VITE_MFE1_REMOTE_URLProduct One remote entry URL
VITE_MFE2_REMOTE_URLProduct Two remote entry URL
VITE_FIREBASE_API_KEYFirebase web API key. Blank (and no emulator host) leaves the shell rendering but with sign-in disabled and a "not configured" banner
VITE_FIREBASE_AUTH_DOMAINFirebase auth domain, e.g. chrono-dev.firebaseapp.com
VITE_FIREBASE_PROJECT_IDFirebase project id; also shown as the tenant in the sidebar footer
VITE_FIREBASE_APP_IDFirebase web app id
VITE_SENTRY_DSNSentry DSN; skip init if absent
VITE_SENTRY_ENVIRONMENTSentry environment tag; production lowers the trace sample rate
VITE_FIREBASE_AUTH_EMULATOR_HOSTe.g. 127.0.0.1:9099 — points the browser session at the Firebase Auth emulator

Every VITE_* value is baked into the bundle at build time — changing one needs a rebuild (locally, a dev-server restart), and the nginx runtime environment of the shipped image cannot override it.

An empty string counts as unset for all of them: the shell falls back to the documented default rather than running on an empty URL or key.

A copy of the full annotated list lives in .env.example at the repository root.