- Consolidate docker-compose files: dev.yml builds locally, main uses pre-built images; remove redundant prod.yml and images.yml - Add docker-entrypoint.sh for database copy from network storage - Add SQLite performance tuning (PRAGMA optimizations, mmap, cache) - Add cache pre-warming for instant first page load - Enhance logging with OTEL-compatible JSON format and trace context - Simplify .env.example with clearer sections and fewer variables - Remove EXTERNAL_IMAGE_URLS env var (auto-read from FP preferences) - Hardcode container ports (use docker port mapping to customize) - Add /api/errors/stats endpoint for admin dashboard
19 KiB
Environment Variables
Complete reference for all environment variables used across all Flashpoint Web services.
Table of Contents
- Overview
- Backend Environment Variables
- Game Service Environment Variables
- Frontend Environment Variables
- Docker Environment Variables
- Environment Templates
- Validation and Defaults
Overview
Flashpoint Web uses environment variables for configuration across three services:
- Backend: API server configuration, database paths, authentication
- Game Service: Proxy settings, ZIP server, game file serving
- Frontend: Build-time API URL configuration
Environment variables are loaded from .env files in each service directory or passed directly via Docker Compose.
Backend Environment Variables
Location: backend/.env
Server Configuration
| Variable | Type | Default | Description |
|---|---|---|---|
NODE_ENV |
string | development |
Environment mode: development, production, test |
PORT |
number | 3100 |
HTTP server port |
HOST |
string | 0.0.0.0 |
Server bind address. Use 127.0.0.1 for localhost only |
Examples:
# Development (all interfaces)
NODE_ENV=development
PORT=3100
HOST=0.0.0.0
# Production (behind reverse proxy)
NODE_ENV=production
PORT=3100
HOST=127.0.0.1
Flashpoint Paths
| Variable | Type | Required | Description |
|---|---|---|---|
FLASHPOINT_PATH |
string | Yes | Root directory of Flashpoint installation. All other paths are automatically derived from this. |
Automatically derived paths:
- Database:
${FLASHPOINT_PATH}/Data/flashpoint.sqlite - HTDOCS:
${FLASHPOINT_PATH}/Legacy/htdocs - Images:
${FLASHPOINT_PATH}/Data/Images - Logos:
${FLASHPOINT_PATH}/Data/Logos - Playlists:
${FLASHPOINT_PATH}/Data/Playlists - Games:
${FLASHPOINT_PATH}/Data/Games
Example (Windows):
FLASHPOINT_PATH=D:/Flashpoint
Example (Linux):
FLASHPOINT_PATH=/data/flashpoint
Example (Docker):
# Inside container (mounted from host)
FLASHPOINT_PATH=/data/flashpoint
Game Service URLs
| Variable | Type | Default | Description |
|---|---|---|---|
GAME_SERVICE_PROXY_URL |
string | http://localhost:22500 |
URL to game-service HTTP proxy |
GAME_SERVICE_GAMEZIP_URL |
string | http://localhost:22501 |
URL to game-service GameZip server |
GAME_SERVER_URL |
string | - | Legacy alias for GAME_SERVICE_PROXY_URL |
GAME_SERVER_HTTP_PORT |
number | - | Legacy alias for GameZip port |
Examples:
# Local development
GAME_SERVICE_PROXY_URL=http://localhost:22500
GAME_SERVICE_GAMEZIP_URL=http://localhost:22501
# Docker (internal network)
GAME_SERVICE_PROXY_URL=http://game-service:22500
GAME_SERVICE_GAMEZIP_URL=http://game-service:22501
# Remote game service
GAME_SERVICE_PROXY_URL=http://192.168.1.100:22500
GAME_SERVICE_GAMEZIP_URL=http://192.168.1.100:22501
Image CDN URLs (Automatic)
Image CDN URLs are automatically read from Flashpoint's preferences file. No environment variable configuration required.
Source: Flashpoint preferences (onDemandBaseUrl from preferences.json or .preferences.defaults.json)
Fallback: If preferences are unavailable, defaults to:
https://infinity.flashpointarchive.org/Flashpoint/Data/Imageshttps://infinity.unstable.life/Flashpoint/Data/Images
When images are not found locally, the backend will try fetching from these CDN URLs in order.
Authentication and Security
| Variable | Type | Default | Description |
|---|---|---|---|
JWT_SECRET |
string | INSECURE-CHANGE-THIS-IN-PRODUCTION |
Secret key for JWT signing (CRITICAL: must change in production!) |
JWT_EXPIRES_IN |
string | 1h |
Access token expiration time (examples: 15m, 1h, 7d) |
BCRYPT_SALT_ROUNDS |
number | 10 |
Bcrypt salt rounds for password hashing (higher = more secure but slower) |
USER_DB_PATH |
string | ./user.db |
Path to user database SQLite file |
CRITICAL: Change JWT_SECRET in production!
Generate a secure secret (64+ characters recommended):
# Linux/Mac
openssl rand -hex 64
# Node.js
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
# PowerShell
-join ((48..57) + (65..90) + (97..122) | Get-Random -Count 64 | % {[char]$_})
Example:
JWT_SECRET=a1b2c3d4e5f6789012345678901234567890abcdefghijklmnopqrstuvwxyz0123
JWT_EXPIRES_IN=1h
BCRYPT_SALT_ROUNDS=12
USER_DB_PATH=./data/user.db
CORS Configuration
| Variable | Type | Default | Description |
|---|---|---|---|
DOMAIN |
string | http://localhost:5173 |
Allowed CORS origin (frontend URL) |
Examples:
# Development
DOMAIN=http://localhost:5173
# Production (single domain)
DOMAIN=https://flashpoint.example.com
# Production (multiple domains - comma-separated)
DOMAIN=https://flashpoint.example.com,https://www.flashpoint.example.com
# Allow all origins (NOT RECOMMENDED)
DOMAIN=*
Rate Limiting
| Variable | Type | Default | Description |
|---|---|---|---|
RATE_LIMIT_WINDOW_MS |
number | 60000 |
Time window in milliseconds (default: 1 minute) |
RATE_LIMIT_MAX_REQUESTS |
number | 100 |
Maximum requests per window |
Examples:
# Strict (1 request per second)
RATE_LIMIT_WINDOW_MS=1000
RATE_LIMIT_MAX_REQUESTS=1
# Default (100 requests per minute)
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=100
# Lenient (1000 requests per 5 minutes)
RATE_LIMIT_WINDOW_MS=300000
RATE_LIMIT_MAX_REQUESTS=1000
# Disable rate limiting
RATE_LIMIT_MAX_REQUESTS=0
Redis Cache (Optional)
| Variable | Type | Default | Description |
|---|---|---|---|
REDIS_ENABLED |
boolean | false |
Enable Redis caching |
REDIS_HOST |
string | localhost |
Redis server hostname |
REDIS_PORT |
number | 6379 |
Redis server port |
Examples:
# Disabled (default)
REDIS_ENABLED=false
# Local Redis
REDIS_ENABLED=true
REDIS_HOST=localhost
REDIS_PORT=6379
# Remote Redis
REDIS_ENABLED=true
REDIS_HOST=redis.example.com
REDIS_PORT=6379
Logging
| Variable | Type | Default | Description |
|---|---|---|---|
LOG_LEVEL |
string | info |
Logging level: error, warn, info, debug |
LOG_FILE |
string | - | Path to log file (optional). If not set, logs only to console. |
Examples:
# Development (verbose, console only)
LOG_LEVEL=debug
# Production (minimal, console only)
LOG_LEVEL=warn
# Production with file logging
LOG_LEVEL=info
LOG_FILE=/var/log/flashpoint-backend.log
# Docker (using volume mount)
LOG_LEVEL=info
LOG_FILE=/app/logs/backend.log
File Logging Features:
- Automatic log rotation (10MB max file size)
- Keeps last 5 log files
- JSON format for easy parsing
- Logs to both console and file when enabled
- Directory created automatically if it doesn't exist
Docker Volume Access:
When running in Docker with file logging enabled, logs are persisted in a named volume:
# View logs from container
docker exec flashpoint-backend tail -f /app/logs/backend.log
# Find volume location on host
docker volume inspect flashpoint-web_backend-logs
# Copy logs to host
docker cp flashpoint-backend:/app/logs/backend.log ./backend.log
OpenTelemetry (Optional - Observability & Monitoring)
| Variable | Type | Default | Description |
|---|---|---|---|
OTEL_ENABLED |
boolean | false |
Enable/disable OpenTelemetry telemetry collection |
OTEL_EXPORTER_OTLP_ENDPOINT |
string | http://localhost:4318 |
OTLP endpoint URL (HTTP protocol) |
OTEL_SERVICE_NAME |
string | flashpoint-web-backend |
Service name for identifying this service in traces/metrics |
OTEL_TRACES_ENABLED |
boolean | true |
Enable/disable distributed tracing |
OTEL_METRICS_ENABLED |
boolean | true |
Enable/disable metrics collection |
OTEL_METRICS_EXPORT_INTERVAL |
number | 60000 |
Metrics export interval in milliseconds (default: 60000 = 1 minute) |
OTEL_LOG_LEVEL |
string | info |
OpenTelemetry log level (error, warn, info, debug) |
Compatible Backends:
- Jaeger (distributed tracing)
- Prometheus (metrics via OTLP)
- Grafana Cloud
- New Relic
- Datadog
- Any OTLP-compatible backend
Examples:
# Disabled (default)
OTEL_ENABLED=false
# Local Jaeger instance
OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
OTEL_SERVICE_NAME=flashpoint-web-backend
OTEL_TRACES_ENABLED=true
OTEL_METRICS_ENABLED=true
# Grafana Cloud
OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp-gateway-prod-us-central-0.grafana.net/otlp
OTEL_SERVICE_NAME=flashpoint-web-production
OTEL_TRACES_ENABLED=true
OTEL_METRICS_ENABLED=true
OTEL_METRICS_EXPORT_INTERVAL=30000
OTEL_LOG_LEVEL=warn
Game Service Environment Variables
Location: game-service/.env
Server Ports
| Variable | Type | Default | Description |
|---|---|---|---|
PROXY_PORT |
number | 22500 |
HTTP proxy server port |
GAMEZIPSERVER_PORT |
number | 22501 |
GameZip server port |
NODE_ENV |
string | development |
Environment mode |
Examples:
# Default ports
PROXY_PORT=22500
GAMEZIPSERVER_PORT=22501
# Custom ports
PROXY_PORT=8500
GAMEZIPSERVER_PORT=8501
Flashpoint Paths
| Variable | Type | Required | Description |
|---|---|---|---|
FLASHPOINT_PATH |
string | Yes | Root Flashpoint directory. All other paths are automatically derived from this. |
Automatically derived paths:
- HTDOCS:
${FLASHPOINT_PATH}/Legacy/htdocs - Games:
${FLASHPOINT_PATH}/Data/Games
Examples:
# Windows
FLASHPOINT_PATH=D:/Flashpoint
# Linux
FLASHPOINT_PATH=/data/flashpoint
Proxy Configuration
| Variable | Type | Default | Description |
|---|---|---|---|
PROXY_CHUNK_SIZE |
number | 8192 |
Chunk size for streaming files (bytes) |
EXTERNAL_FALLBACK_URLS |
string | See below | Comma-separated CDN URLs for external fallback |
Default Fallback URLs:
EXTERNAL_FALLBACK_URLS=http://infinity.flashpointarchive.org/Flashpoint/Legacy/htdocs,http://infinity.unstable.life/Flashpoint/Legacy/htdocs/
Examples:
# Default settings
PROXY_CHUNK_SIZE=8192
# Large files optimization (64KB chunks)
PROXY_CHUNK_SIZE=65536
# Single fallback URL
EXTERNAL_FALLBACK_URLS=http://infinity.flashpointarchive.org/Flashpoint/Legacy/htdocs
# Custom fallback URLs
EXTERNAL_FALLBACK_URLS=https://cdn1.example.com,https://cdn2.example.com
Advanced Features
| Variable | Type | Default | Description |
|---|---|---|---|
ENABLE_CGI |
boolean | false |
Enable CGI script execution (experimental) |
ENABLE_HTACCESS |
boolean | false |
Enable .htaccess processing (experimental) |
Examples:
# Enable advanced features (use with caution)
ENABLE_CGI=true
ENABLE_HTACCESS=true
Logging
| Variable | Type | Default | Description |
|---|---|---|---|
LOG_LEVEL |
string | info |
Logging level |
LOG_REQUESTS |
boolean | true |
Log HTTP requests |
LOG_ERRORS |
boolean | true |
Log errors |
Examples:
# Verbose logging
LOG_LEVEL=debug
LOG_REQUESTS=true
LOG_ERRORS=true
# Minimal logging
LOG_LEVEL=warn
LOG_REQUESTS=false
LOG_ERRORS=true
Frontend Environment Variables
Location: frontend/.env (build time only)
Build Configuration
| Variable | Type | Default | Description |
|---|---|---|---|
VITE_API_URL |
string | http://localhost:3100 |
Backend API URL |
IMPORTANT: Frontend environment variables are embedded at build time. Changes require rebuild.
Examples:
# Development
VITE_API_URL=http://localhost:3100
# Production (same domain)
VITE_API_URL=https://flashpoint.example.com
# Production (API subdomain)
VITE_API_URL=https://api.flashpoint.example.com
# Production (different port)
VITE_API_URL=https://flashpoint.example.com:8443
Build with Custom API URL
# Option 1: Set in .env file
echo "VITE_API_URL=https://api.example.com" > frontend/.env
npm run build
# Option 2: Inline environment variable
VITE_API_URL=https://api.example.com npm run build
# Option 3: Docker build arg
docker build --build-arg VITE_API_URL=https://api.example.com -t frontend .
Docker Environment Variables
Location: Docker Compose .env or docker-compose.yml
Docker Compose Variables
| Variable | Type | Default | Description |
|---|---|---|---|
FLASHPOINT_HOST_PATH |
string | D:/Flashpoint |
Host path to Flashpoint installation |
NODE_ENV |
string | production |
Environment for all services |
WEB_PORT |
number | 80 |
Frontend exposed port |
API_PORT |
number | 3100 |
Backend exposed port |
PROXY_PORT |
number | 22500 |
Game proxy exposed port |
GAMEZIP_PORT |
number | 22501 |
GameZip exposed port |
LOG_LEVEL |
string | info |
Logging level for all services |
DOMAIN |
string | http://localhost |
CORS origin |
Docker Compose .env file:
# .env in project root
FLASHPOINT_HOST_PATH=D:/Flashpoint
NODE_ENV=production
WEB_PORT=80
API_PORT=3100
PROXY_PORT=22500
GAMEZIP_PORT=22501
LOG_LEVEL=info
DOMAIN=http://localhost
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
Using Docker Environment Files
Option 1: .env file (recommended)
# Create .env in project root
cat > .env << EOF
FLASHPOINT_HOST_PATH=/data/flashpoint
JWT_SECRET=$(openssl rand -hex 64)
DOMAIN=https://flashpoint.example.com
EOF
# Start with .env
docker-compose up -d
Option 2: Custom env file
# Create custom file
cat > production.env << EOF
FLASHPOINT_HOST_PATH=/data/flashpoint
NODE_ENV=production
EOF
# Use with docker-compose
docker-compose --env-file production.env up -d
Option 3: Inline variables
FLASHPOINT_HOST_PATH=/data/flashpoint \
JWT_SECRET=my-secret \
docker-compose up -d
Environment Templates
Development Template
Create backend/.env.development:
# Server
NODE_ENV=development
PORT=3100
HOST=0.0.0.0
# Flashpoint paths
FLASHPOINT_PATH=D:/Flashpoint
FLASHPOINT_DB_PATH=D:/Flashpoint/Data/flashpoint.sqlite
FLASHPOINT_HTDOCS_PATH=D:/Flashpoint/Legacy/htdocs
FLASHPOINT_IMAGES_PATH=D:/Flashpoint/Data/Images
FLASHPOINT_LOGOS_PATH=D:/Flashpoint/Data/Logos
FLASHPOINT_PLAYLISTS_PATH=D:/Flashpoint/Data/Playlists
FLASHPOINT_GAMES_PATH=D:/Flashpoint/Data/Games
# Game service
GAME_SERVICE_PROXY_URL=http://localhost:22500
GAME_SERVICE_GAMEZIP_URL=http://localhost:22501
# Security (weak for dev only)
JWT_SECRET=development-secret-change-in-production
DOMAIN=http://localhost:5173
# Rate limiting (lenient)
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=1000
# Logging (verbose)
LOG_LEVEL=debug
# Redis (disabled)
REDIS_ENABLED=false
Production Template
Create backend/.env.production:
# Server
NODE_ENV=production
PORT=3100
HOST=127.0.0.1
# Flashpoint paths
FLASHPOINT_PATH=/data/flashpoint
FLASHPOINT_DB_PATH=/data/flashpoint/Data/flashpoint.sqlite
FLASHPOINT_HTDOCS_PATH=/data/flashpoint/Legacy/htdocs
FLASHPOINT_IMAGES_PATH=/data/flashpoint/Data/Images
FLASHPOINT_LOGOS_PATH=/data/flashpoint/Data/Logos
FLASHPOINT_PLAYLISTS_PATH=/data/flashpoint/Data/Playlists
FLASHPOINT_GAMES_PATH=/data/flashpoint/Data/Games
# Game service
GAME_SERVICE_PROXY_URL=http://localhost:22500
GAME_SERVICE_GAMEZIP_URL=http://localhost:22501
# Security (CHANGE THESE!)
JWT_SECRET=CHANGE-THIS-TO-A-RANDOM-64-CHARACTER-STRING
DOMAIN=https://flashpoint.example.com
# Rate limiting
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=100
# Logging
LOG_LEVEL=warn
LOG_FILE=/var/log/flashpoint-backend.log
# Redis (enabled)
REDIS_ENABLED=true
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_TTL=3600
# Database
USER_DB_PATH=/opt/flashpoint-web/backend/data/user.db
DB_POOL_SIZE=20
Docker Production Template
Create .env in project root:
# Host configuration
FLASHPOINT_HOST_PATH=/data/flashpoint
# Environment
NODE_ENV=production
# Ports
WEB_PORT=80
API_PORT=3100
PROXY_PORT=22500
GAMEZIP_PORT=22501
# Security
JWT_SECRET=CHANGE-THIS-TO-A-RANDOM-64-CHARACTER-STRING
DOMAIN=https://flashpoint.example.com
# Logging
LOG_LEVEL=warn
# External URLs (game content fallback)
EXTERNAL_FALLBACK_URLS=http://infinity.flashpointarchive.org/Flashpoint/Legacy/htdocs,http://infinity.unstable.life/Flashpoint/Legacy/htdocs/
# Note: Image CDN URLs are automatically read from Flashpoint preferences
# API URL (for frontend build)
VITE_API_URL=https://flashpoint.example.com
Validation and Defaults
Environment Validation
The backend validates environment variables on startup:
// backend/src/config.ts
import { z } from 'zod';
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
PORT: z.coerce.number().min(1).max(65535).default(3100),
HOST: z.string().default('0.0.0.0'),
FLASHPOINT_PATH: z.string().min(1),
JWT_SECRET: z.string().min(32),
// ... more validations
});
export const config = envSchema.parse(process.env);
Required Variables
These variables MUST be set or the application will fail to start:
Backend:
FLASHPOINT_PATHFLASHPOINT_DB_PATHFLASHPOINT_HTDOCS_PATHFLASHPOINT_IMAGES_PATHFLASHPOINT_LOGOS_PATHFLASHPOINT_PLAYLISTS_PATHFLASHPOINT_GAMES_PATH
Game Service:
FLASHPOINT_PATHFLASHPOINT_HTDOCS_PATHFLASHPOINT_GAMES_PATH
Production (Backend):
JWT_SECRET(must be changed from default)DOMAIN(must match frontend URL)
Checking Configuration
Test configuration without starting services:
# Backend
cd backend
node -e "require('dotenv').config(); console.log(process.env)"
# Validate Flashpoint paths exist
node -e "require('dotenv').config(); const fs=require('fs'); console.log(fs.existsSync(process.env.FLASHPOINT_DB_PATH) ? 'OK' : 'NOT FOUND')"
Security Best Practices
- Never commit .env files to version control
- Use strong JWT secrets in production (64+ characters)
- Restrict CORS origins to your domain only
- Use HTTPS in production (update DOMAIN)
- Limit exposed ports in Docker (don't expose all services)
- Rotate secrets periodically
- Use environment-specific files (.env.production, .env.development)
- Validate all inputs before use
- Keep secrets in secure storage (AWS Secrets Manager, HashiCorp Vault)
- Use read-only mounts for Flashpoint data in Docker
Next Steps
- Docker Deployment - Container configuration
- Production Setup - Production environment setup
- Security Considerations - Security hardening guide