Skip to Content
Configuration

Environment Variable Reference

Bliss uses a single root .env file as the source of truth for all services. Both the Next.js API layer and the Express backend service read from this shared file, ensuring configuration stays consistent across the stack.

How it works

  • Docker Compose reads the root .env automatically — no env_file directive needed.
  • scripts/setup.sh generates cryptographic secrets (ENCRYPTION_SECRET, JWT_SECRET_CURRENT, NEXTAUTH_SECRET, INTERNAL_API_KEY) so you never have to create them by hand. Run it once after copying .env.example to .env.
  • Optional integrations (Plaid, Twelve Data, CurrencyLayer, Sentry) are activated simply by adding the relevant API keys. The application degrades gracefully when they are absent. The LLM provider (Gemini, OpenAI, or Anthropic) is the one required integration — without it AI classification and insights are unavailable.
  • Test-specific overrides: each service may have a .env.test file that overrides DATABASE_URL to point at an isolated test database. These files are loaded automatically by the test runners and should never be committed.

Minimal Docker Setup

For a basic Docker deployment, scripts/setup.sh generates all required secrets automatically (ENCRYPTION_SECRET, JWT_SECRET_CURRENT, NEXTAUTH_SECRET, INTERNAL_API_KEY). It also sets safe defaults for DATABASE_URL, REDIS_URL, and all service URLs. You do not need to configure anything to get a working local instance.

The one required integration is an LLM provider for AI classification and insights. The optional ones add useful features but degrade gracefully:

IntegrationRequired?VariablesPurpose
LLM (Gemini / OpenAI / Anthropic)YesLLM_PROVIDER, GEMINI_API_KEY / OPENAI_API_KEY / ANTHROPIC_API_KEYAI classification + insights
PlaidNoPLAID_CLIENT_ID, PLAID_SECRETBank account linking
Market dataNoTWELVE_DATA_API_KEYStock price fetching
Currency ratesNoCURRENCYLAYER_API_KEYAutomatic FX rate fetching
ObservabilityNoSENTRY_DSNError tracking

See Choosing Your External Services for picking and configuring an LLM. Optional integrations can be added any time.


Database

VariableRequiredDefaultDescription
DATABASE_URLYespostgresql://bliss:changeme@localhost:5432/blissPostgreSQL connection string used by Prisma in both services. Inside Docker the host is postgres instead of localhost.
POSTGRES_PASSWORDYeschangemeSuperuser password passed to the postgres Docker image to bootstrap the database.

Redis

VariableRequiredDefaultDescription
REDIS_URLYesredis://:changeme@localhost:6379Full Redis connection URL (include password if set). Used by BullMQ queues and workers.
REDIS_PASSWORDYeschangemePassword for the redis Docker service. Must match the password embedded in REDIS_URL.
REDIS_SKIP_TLS_CHECKNofalseSet to true when Redis uses TLS with a self-signed certificate. For managed services like Upstash, leave as false.

Secrets

All four required secrets in this section are generated by scripts/setup.sh.

VariableRequiredDefaultDescription
ENCRYPTION_SECRETYesAES-256-GCM key used to encrypt PII fields (transaction descriptions, account numbers, Plaid access tokens). Minimum 32 characters.
ENCRYPTION_SECRET_PREVIOUSNoSet during encryption key rotation. The application will try the previous key when decryption with the current key fails. Remove once migration is complete.
JWT_SECRET_CURRENTYesHMAC secret used to sign and verify JWT access tokens.
JWT_SECRET_PREVIOUSNoSet during JWT secret rotation. Tokens signed with the previous secret remain valid until they expire.
NEXTAUTH_SECRETYesSecret used by NextAuth.js for session cookie signing.
INTERNAL_API_KEYYesShared secret for server-to-server calls between the API layer and the backend service. Must be identical in both services.

API Layer (Next.js)

VariableRequiredDefaultDescription
NEXTAUTH_URLYeshttp://localhost:3000Full public URL of the Next.js API layer. Used by NextAuth for callback URLs.
BACKEND_URLYeshttp://localhost:3001Internal URL of the Express backend service. Used for server-to-server event dispatch and proxy routes. Not exposed to the browser.
COOKIE_DOMAINNoCookie domain for cross-subdomain auth (e.g., .bliss.finance). Leave empty for localhost development.

Backend Service (Express)

VariableRequiredDefaultDescription
PORTNo3001Port the Express backend listens on.
ALLOWED_ORIGINSNohttp://localhost:3000Comma-separated list of allowed CORS origins for the backend.

Storage

File upload storage is pluggable. The default is local disk; switch to Google Cloud Storage by setting STORAGE_BACKEND=gcs and providing the GCS variables.

VariableRequiredDefaultDescription
STORAGE_BACKENDNolocallocal for filesystem storage, gcs for Google Cloud Storage.
LOCAL_STORAGE_DIRNo./data/uploadsDirectory for uploaded files when using local storage.
GCS_BUCKET_NAMENoGCS bucket name. Required when STORAGE_BACKEND=gcs.
GCS_SERVICE_ACCOUNT_JSONNoGCS service account credentials as a JSON string. Required when STORAGE_BACKEND=gcs.

Frontend

VariableRequiredDefaultDescription
NEXT_PUBLIC_API_URLYeshttp://localhost:3000Public URL of the API layer, baked into the web bundle at build time. Changing it requires a rebuild.
FRONTEND_URLYeshttp://localhost:8080Public URL of the frontend app. Used by the API layer for CORS whitelisting.

Plaid (optional)

Plaid integration is optional. CSV import works without it. To enable bank-account linking, provide a Plaid client ID and secret.

VariableRequiredDefaultDescription
PLAID_CLIENT_IDNoPlaid API client ID.
PLAID_SECRETNoPlaid API secret.
PLAID_ENVNosandboxPlaid environment: sandbox, development, or production.
PLAID_WEBHOOK_URLNoPublic URL for Plaid webhook delivery. Required in production to receive transaction updates.
PLAID_HISTORY_DAYSNo1Default number of days of transaction history fetched on initial Plaid link. Written to Tenant.plaidHistoryDays at signup.

AI / LLM Provider

Bliss supports three LLM providers for transaction classification and financial insights: Google Gemini, OpenAI, and Anthropic Claude. An LLM provider is required for AI classification and insights. Pick one in .env.

See the Choosing Your External Services guide for per-provider setup, model overrides, and switching workflows.

VariableRequiredDefaultDescription
LLM_PROVIDERYesgeminiWhich provider powers classification and insights. One of: gemini, openai, anthropic.
EMBEDDING_PROVIDERWhen LLM_PROVIDER=anthropic(follows LLM_PROVIDER)Override embedding provider. Required when using Anthropic because Anthropic has no embedding API. Must be gemini or openai.
GEMINI_API_KEYWhen LLM_PROVIDER=gemini (or EMBEDDING_PROVIDER=gemini)Google Gemini API key.
OPENAI_API_KEYWhen LLM_PROVIDER=openai (or EMBEDDING_PROVIDER=openai)OpenAI API key.
ANTHROPIC_API_KEYWhen LLM_PROVIDER=anthropicAnthropic API key.
EMBEDDING_MODELNogemini-embedding-001 / text-embedding-3-small / (n/a)Override the embedding model for the active embedding provider. Output is projected to 768 dimensions.
CLASSIFICATION_MODELNogemini-3-flash-preview / gpt-4.1-mini / claude-sonnet-4-6Override the classification model for the active LLM provider.
INSIGHT_MODELNogemini-3.1-pro-preview / gpt-4.1 / claude-sonnet-4-6Override the insights model for the active LLM provider.

Graceful degradation: Missing the primary LLM provider key produces a warning and disables AI classification + insights (the rest of the app keeps working). Missing the secondary EMBEDDING_PROVIDER key when you opted in explicitly is a hard startup error.

Market Data (optional)

Stock price fetching is provided by Twelve Data  by default and is disabled when no API key is set.

VariableRequiredDefaultDescription
STOCK_PROVIDERNoTWELVE_DATAStock data provider. Supported values: TWELVE_DATA (recommended), FINNHUB.
TWELVE_DATA_API_KEYNoAPI key for Twelve Data. Enables real-time and historical pricing for stocks, ETFs, and funds (10,000+ symbols across 27+ markets).
FINNHUB_API_KEYNoAPI key for Finnhub. Alternative stock data provider.

Currency Rates (optional)

Automatic historical exchange rate fetching is disabled when the API key is not set. Rates can still be entered manually via the UI.

VariableRequiredDefaultDescription
CURRENCYLAYER_API_KEYNoAPI key for CurrencyLayer . Used by portfolio processing and analytics to fetch historical FX rates.

Observability (optional)

Error tracking and performance monitoring via Sentry. Leave all three unset to disable.

VariableRequiredDefaultDescription
SENTRY_DSNNoSentry Data Source Name. Enables error reporting when set.
SENTRY_ORGNoSentry organization slug. Used for source-map uploads during CI builds.
SENTRY_PROJECTNoSentry project slug. Used alongside SENTRY_ORG for source-map uploads.