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

9.9 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 (src/Website)

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 (src/Website)

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: src/Website/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

Admin Account (Seeding)

ADMIN_PASSWORD=SecureAdminPassword123!   # Initial admin password for seeding
  • Required: No (only needed for seeding)
  • Purpose: Sets admin account password during database seeding
  • Security: Use strong password, change immediately in production

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 (Root Directory)

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

Setup:

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

Legacy Frontend Variables

Variables for the archived Next.js frontend (src/Website-v1) have been removed from this active reference. See archive/legacy-website-v1.md if you need the legacy Prisma, Cloudinary, Mapbox, or SparkPost notes.

Docker Compose Mapping:

  • docker-compose.dev.yaml.env.dev
  • docker-compose.test.yaml.env.test
  • docker-compose.prod.yaml.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
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 cause application to fail
  • JWT_SECRET length is enforced (min 32 chars)
  • Connection string format is validated

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

# 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