Files
the-biergarten-app/docs/website/environment-variables.md

12 KiB

Environment Variables

This document covers the active environment variables used by the current Biergarten stack.

Overview

The application uses environment variables for:

  • .NET API backend - database connections, token secrets, runtime settings
  • React Router website - API base URL and session signing
  • Docker containers - environment-specific orchestration

Configuration Patterns

Backend (.NET API)

Direct environment variable access via Environment.GetEnvironmentVariable().

Frontend (web/frontend)

The active website reads runtime values from the server environment for its auth and API integration.

Docker

Environment-specific .env files loaded via env_file: in docker-compose.yaml:

  • .env.dev - Development
  • .env.test - Testing
  • .env.prod - Production

Backend Variables (.NET API)

Database Connection

Option 1: Component-Based (Recommended for Docker)

Build connection string from individual components:

DB_SERVER=sqlserver,1433          # SQL Server host and port
DB_NAME=Biergarten                # Database name
DB_USER=sa                        # SQL Server username
DB_PASSWORD=YourStrong!Passw0rd   # SQL Server password
DB_TRUST_SERVER_CERTIFICATE=True  # Optional, defaults to True

Option 2: Full Connection String (Local Development)

Provide complete connection string:

DB_CONNECTION_STRING="Server=localhost,1433;Database=Biergarten;User Id=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True;"

Priority: DB_CONNECTION_STRING is checked first. If not found, connection string is built from components.

Implementation: See DefaultSqlConnectionFactory.cs

JWT Authentication Secrets (Backend)

The backend uses separate secrets for different token types to enable independent key rotation and validation isolation.

# Access token secret (1-hour tokens)
ACCESS_TOKEN_SECRET=<generated-secret>              # Signs short-lived access tokens

# Refresh token secret (21-day tokens)
REFRESH_TOKEN_SECRET=<generated-secret>             # Signs long-lived refresh tokens

# Confirmation token secret (30-minute tokens)
CONFIRMATION_TOKEN_SECRET=<generated-secret>        # Signs email confirmation tokens

# Website base URL (used in confirmation emails)
WEBSITE_BASE_URL=https://thebiergarten.app          # Base URL for the website

Security Requirements:

  • Each secret should be minimum 32 characters
  • Recommend 127+ characters for production
  • Generate using cryptographically secure random functions
  • Never reuse secrets across token types or environments
  • Rotate secrets periodically in production

Generate Secrets:

# macOS/Linux - Generate 127-character base64 secret
openssl rand -base64 127

# Windows PowerShell
[Convert]::ToBase64String((1..127 | %{Get-Random -Max 256}))

Token Expiration:

  • Access tokens: 1 hour
  • Refresh tokens: 21 days
  • Confirmation tokens: 30 minutes

(Defined in TokenServiceExpirationHours class)

JWT Implementation:

  • Algorithm: HS256 (HMAC-SHA256)
  • Handler: Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler
  • Validation: Token signature, expiration, and malformed token checks

Migration Control

CLEAR_DATABASE=true
  • Required: No
  • Default: false
  • Effect: If "true", drops and recreates database during migrations
  • Usage: Development and testing environments ONLY
  • Warning: NEVER use in production

ASP.NET Core Configuration

ASPNETCORE_ENVIRONMENT=Development    # Development, Production, Staging
ASPNETCORE_URLS=http://0.0.0.0:8080  # Binding address and port
DOTNET_RUNNING_IN_CONTAINER=true     # Flag for container execution

Frontend Variables (web/frontend)

The active website does not use the old Next.js/Prisma environment model. Its core runtime variables are:

API_BASE_URL=http://localhost:8080       # Base URL for the .NET API
SESSION_SECRET=<generated-secret>        # Cookie session signing secret
NODE_ENV=development                     # Standard Node runtime mode

Frontend Variable Details

API_BASE_URL

  • Required: Yes for local development
  • Default in code: http://localhost:8080
  • Used by: web/frontend/app/lib/auth.server.ts
  • Purpose: Routes website auth actions to the .NET API

SESSION_SECRET

  • Required: Strongly recommended in all environments
  • Default in local code path: dev-secret-change-me
  • Used by: React Router cookie session storage in auth.server.ts
  • Purpose: Signs and validates the website session cookie

NODE_ENV

  • Required: No
  • Typical values: development, production, test
  • Purpose: Controls secure cookie behavior and runtime mode

SMTP Configuration (Backend)

Read by Infrastructure.Email/SmtpEmailProvider.cs for sending confirmation and account emails.

SMTP_HOST=mailpit                        # Required, no default
SMTP_PORT=1025                           # Optional, defaults to 587
SMTP_USERNAME=<username>                 # Optional, no default
SMTP_PASSWORD=<password>                 # Optional, no default
SMTP_USE_SSL=false                       # Optional, defaults to true
SMTP_FROM_EMAIL=noreply@thebiergarten.app # Required, no default
SMTP_FROM_NAME=The Biergarten App        # Optional, defaults to "The Biergarten"
  • Implementation: Infrastructure.Email/SmtpEmailProvider.cs throws on startup if SMTP_HOST or SMTP_FROM_EMAIL is missing
  • Local dev: point at the mailpit Docker service (SMTP on port 1025, web UI on http://localhost:8025)
  • Production: point at a real provider (SendGrid, Mailgun, Amazon SES, etc.)

Docker-Specific Variables

SQL Server Container

SA_PASSWORD=YourStrong!Passw0rd   # SQL Server SA password
ACCEPT_EULA=Y                     # Accept SQL Server EULA (required)
MSSQL_PID=Express                 # SQL Server edition (Express, Developer, Enterprise)

Password Requirements:

  • Minimum 8 characters
  • Uppercase, lowercase, digits, and special characters
  • Maps to DB_PASSWORD for application containers

Environment File Structure

Backend/Docker (web/ Directory)

web/.env.example          # Template (tracked in Git)
web/.env.dev             # Development config (gitignored)
web/.env.test            # Testing config (gitignored)
web/.env.prod            # Production config (gitignored)

Setup:

cp web/.env.example web/.env.dev
# Edit web/.env.dev with your values

Legacy Frontend Variables

Variables for the archived Next.js frontend (archive/next-js-web-app/) have been removed from this active reference, since that app is retained for reference only and is not run as part of the active stack.

Docker Compose Mapping:

  • web/docker-compose.dev.yamlweb/.env.dev
  • web/docker-compose.test.yamlweb/.env.test
  • web/docker-compose.prod.yamlweb/.env.prod

Variable Reference Table

Variable Backend Frontend Docker Required Notes
DB_SERVER Yes* SQL Server address
DB_NAME Yes* Database name
DB_USER Yes* SQL username
DB_PASSWORD Yes* SQL password
DB_CONNECTION_STRING Yes* Alternative to components
DB_TRUST_SERVER_CERTIFICATE No Defaults to True
ACCESS_TOKEN_SECRET Yes Access token signing
REFRESH_TOKEN_SECRET Yes Refresh token signing
CONFIRMATION_TOKEN_SECRET Yes Confirmation token signing
WEBSITE_BASE_URL Yes Website URL for emails
SMTP_HOST Yes SMTP server host
SMTP_PORT No Defaults to 587
SMTP_USERNAME No SMTP auth username
SMTP_PASSWORD No SMTP auth password
SMTP_USE_SSL No Defaults to true
SMTP_FROM_EMAIL Yes Email sender address
SMTP_FROM_NAME No Defaults to The Biergarten
API_BASE_URL Yes Website-to-API base URL
SESSION_SECRET Yes Website session signing
NODE_ENV No Runtime mode
CLEAR_DATABASE No Dev/test reset flag
ASPNETCORE_ENVIRONMENT Yes ASP.NET environment
ASPNETCORE_URLS Yes API binding address
SA_PASSWORD Yes SQL Server container
ACCEPT_EULA Yes SQL Server EULA
MSSQL_PID No SQL Server edition
DOTNET_RUNNING_IN_CONTAINER No Container flag

* Either DB_CONNECTION_STRING OR the component variables (DB_SERVER, DB_NAME, DB_USER, DB_PASSWORD) must be provided.

Validation

Backend Validation

Variables are validated at startup:

  • Missing required variables (ACCESS_TOKEN_SECRET, REFRESH_TOKEN_SECRET, CONFIRMATION_TOKEN_SECRET, SMTP_HOST, SMTP_FROM_EMAIL, DB connection values) cause the application to fail with an InvalidOperationException
  • No minimum length is enforced on the token secrets in code; the "minimum 32 characters" guidance above is a recommendation, not an enforced check

Frontend Validation

The active website relies on runtime defaults for local development and the surrounding server environment in deployed environments.

  • API_BASE_URL defaults to http://localhost:8080
  • SESSION_SECRET falls back to a development-only local secret
  • NODE_ENV controls secure cookie behavior

Example Configuration Files

.env.dev (Backend/Docker)

# Database
DB_SERVER=sqlserver,1433
DB_NAME=Biergarten
DB_USER=sa
DB_PASSWORD=Dev_Password_123!

# JWT Authentication Secrets
ACCESS_TOKEN_SECRET=<generated-with-openssl>
REFRESH_TOKEN_SECRET=<generated-with-openssl>
CONFIRMATION_TOKEN_SECRET=<generated-with-openssl>
WEBSITE_BASE_URL=http://localhost:3000

# SMTP (Mailpit in dev)
SMTP_HOST=mailpit
SMTP_PORT=1025
SMTP_USE_SSL=false
SMTP_FROM_EMAIL=noreply@thebiergarten.app
SMTP_FROM_NAME=The Biergarten App

# Migration
CLEAR_DATABASE=true

# ASP.NET Core
ASPNETCORE_ENVIRONMENT=Development
ASPNETCORE_URLS=http://0.0.0.0:8080

# SQL Server Container
SA_PASSWORD=Dev_Password_123!
ACCEPT_EULA=Y
MSSQL_PID=Express

Frontend local runtime example

API_BASE_URL=http://localhost:8080
SESSION_SECRET=<generated-with-openssl>
NODE_ENV=development