14 KiB
Environment Variables
Configuration reference for all Dotcom Arcade services.
Backend Variables
Location: backend/.env (local development)
Server:
| Variable | Default | Description |
|---|---|---|
NODE_ENV |
development | Environment: development, production, test |
Note: Port (3100) and bind address (0.0.0.0) are hardcoded in the backend. In Docker, use
API_PORTto map a different host port to the container.
Paths:
| Variable | Default | Description |
|---|---|---|
FLASHPOINT_PATH |
D:/Flashpoint (dev), /data/flashpoint (prod) |
Root Flashpoint directory. All other paths auto-derived. Edition (Infinity/Ultimate) auto-detected from version.txt. |
FLASHPOINT_GAMES_PATH |
<FLASHPOINT_PATH>/Data/Games |
Override game ZIP directory (rarely needed). |
APP_VERSION |
set by the Docker build | Release version the server reports on Settings → Update. Baked into the official image from the release tag; set it by hand for a non-Docker deployment, or update checks stay off. |
Authentication & Security:
| Variable | Default | Description |
|---|---|---|
JWT_SECRET |
auto-generated (dev) | Secret for JWT signing (required in production) |
JWT_EXPIRES_IN |
1h | Access token expiration (15m, 1h, 7d, etc.) |
BCRYPT_SALT_ROUNDS |
10 | Password hash cost (higher = more secure but slower) |
DOMAIN |
http://localhost:5173 | Allowed CORS origin(s), comma-separated (see below) |
COOKIE_SECURE |
auto | Secure flag on auth cookies: auto, true, false |
UV_THREADPOOL_SIZE |
16 | Concurrent file I/O threads (Node's own default is 4) |
DB_WORKER_COUNT |
4 | Read-only SQLite query workers (1-16) |
Generate secure JWT secret:
openssl rand -hex 64
COOKIE_SECURE — auth cookies over HTTP and HTTPS:
Browsers discard a cookie marked Secure when it arrives over plain HTTP, which
logs users straight back out. auto therefore decides per request: cookies are
marked Secure only on connections that actually used TLS, so one deployment can
serve a LAN over HTTP and the internet over HTTPS at the same time.
Detection reads X-Forwarded-Proto, which is trusted only from a proxy. Set
COOKIE_SECURE=true if your TLS-terminating proxy does not send that header, and
false only if you deliberately want the flag off everywhere.
DOMAIN — allowed origins:
DOMAIN accepts one origin or a comma-separated list, so a single deployment can
be reached over several addresses:
DOMAIN=http://192.168.0.118,https://flashpoint.example.com
The first entry is the primary origin, used where a single value is required. Requests from any listed origin are accepted, as are requests from hostnames in the domains table.
Two notes that save debugging time:
- Same-origin requests are always allowed, so
SERVE_FRONTEND=truedeployments work at any address without listing it here. You only needDOMAINwhen the UI is served from a different origin than the API, or behind a reverse proxy that rewrites theHostheader. - Default ports are normalized away:
http://host:80andhttp://hostare treated as the same origin, as arehttps://host:443andhttps://host. Non-default ports must be written out, for examplehttp://host:8080.
Rate Limiting:
| Variable | Default | Description |
|---|---|---|
RATE_LIMIT_WINDOW_MS |
60000 | Time window (ms) |
RATE_LIMIT_MAX_REQUESTS |
100 | Max requests per window |
Logging:
| Variable | Default | Description |
|---|---|---|
LOG_LEVEL |
info | Level: error, warn, info, debug |
LOG_FILE |
/app/logs/backend.log (prod) |
Log file path (unset in dev = stdout only) |
Database Performance:
| Variable | Default | Description |
|---|---|---|
ENABLE_LOCAL_DB_COPY |
false | Copy flashpoint.sqlite locally (for network storage SMB/NFS) |
SQLITE_CACHE_SIZE |
-64000 | SQLite page cache size (negative = KB, -64000 = 64MB) |
SQLITE_MMAP_SIZE |
268435456 | Memory-mapped I/O size in bytes (256MB) |
ENABLE_CACHE_PREWARM |
true | Pre-load common queries on startup |
Game Content Serving:
| Variable | Default | Description |
|---|---|---|
ENABLE_CGI |
false | Enable PHP CGI execution for legacy game content |
Frontend Serving:
The backend serves the built React UI in the single-image deployment, so the app and API share one origin.
| Variable | Default | Description |
|---|---|---|
SERVE_FRONTEND |
true in production, else false | Serve the built frontend and SPA fallback from the backend |
FRONTEND_DIST_PATH |
<backend>/../frontend/dist |
Location of the built frontend (rarely needed) |
RUFFLE_DATA_PATH |
/app/data/ruffle in production |
Where Ruffle is installed. Must sit on a mounted volume, or an in-app update is lost when the container is recreated |
Images and updates:
| Variable | Default | Description |
|---|---|---|
IMAGE_PREFIX |
- | Registry path to pull images from, ending in /. Unset builds them from source |
IMAGE_TAG |
latest |
Image tag to build or pull |
APP_UPDATE_URL |
- | "Latest release" API URL (GitHub or Gitea) that Settings checks for new versions; off when unset |
Streaming:
Games that can't run in a browser, such as Java applets and Shockwave, can be
streamed by the session manager under streaming/. It runs under the
streaming compose profile. See Streaming.
| Variable | Default | Description |
|---|---|---|
STREAMING_API_URL |
http://session-manager:8080 |
Session manager's internal API |
STREAMING_STREAM_URL |
http://session-manager:8081 |
Where the app proxies /stream/ to |
STREAMING_API_TOKEN |
- | Token shared with the session manager. Streaming is off without it |
Trusted Header Login:
See also Proxy Sign-In.
When a reverse proxy such as Authentik (forward auth) authenticates users in
front of flashpoint-web, it can pass the signed-in username in a header so
users don't log in twice. The backend believes the header only on connections
from TRUSTED_PROXIES, checked against the connection's own address, not
X-Forwarded-For. The proxy must always set the header, overwriting anything a
client sends, and flashpoint-web must not be reachable from untrusted networks
except through it.
Users are matched by username, so an existing account of that name is signed in; otherwise an account is created (the first one as admin, as with registration). New accounts get a random password. While signed in through the proxy, users can set a password from Settings without knowing the current one, then log in with it when reaching flashpoint-web without the proxy, such as on a LAN.
| Variable | Default | Description |
|---|---|---|
TRUSTED_HEADER_USERNAME |
- | Header holding the username, e.g. X-authentik-username |
TRUSTED_HEADER_EMAIL |
- | Optional header holding the email used for new accounts |
TRUSTED_PROXIES |
- | Comma-separated proxy addresses or CIDR ranges allowed to set the header |
With nginx and Authentik's forward auth, each protected location needs these
lines once. Authentik's generated nginx snippet already includes them; adding
them again sends each header twice:
auth_request_set $authentik_username $upstream_http_x_authentik_username;
auth_request_set $authentik_email $upstream_http_x_authentik_email;
proxy_set_header X-authentik-username $authentik_username;
proxy_set_header X-authentik-email $authentik_email;
OpenTelemetry:
| Variable | Default | Description |
|---|---|---|
OTEL_ENABLED |
false | Enable distributed tracing and metrics |
OTEL_EXPORTER_OTLP_ENDPOINT |
http://localhost:4318 | OTLP collector endpoint |
OTEL_API_KEY |
- | API key for authentication |
OTEL_SERVICE_NAME |
flashpoint-web | Service name in traces/metrics |
OTEL_TRACES_ENABLED |
true | Enable trace export (when OTEL enabled) |
OTEL_METRICS_ENABLED |
true | Enable metrics export (when OTEL enabled) |
OTEL_METRICS_EXPORT_INTERVAL |
60000 | Metrics export interval (ms) |
OTEL_LOG_LEVEL |
info | OTEL SDK log level |
Frontend Variables
The frontend has no environment variables of its own. API calls use relative
paths (/api), so they resolve against whatever origin serves the app.
- Development: Vite dev server on port 5173 proxies
/apitohttp://localhost:3100 - Production: The backend serves the built UI and the API from the same origin
Docker Environment Variables
Location: .env in project root (used by docker-compose)
Required:
| Variable | Description |
|---|---|
FLASHPOINT_HOST_PATH |
Host path to Flashpoint installation (bind-mounted as ro) |
JWT_SECRET |
Secret for JWT signing (generate with openssl rand -hex 64) |
Port Mapping:
| Variable | Default | Description |
|---|---|---|
WEB_PORT |
80 | Host port mapped to the container (serves UI + API) |
Container Settings:
| Variable | Default | Description |
|---|---|---|
PUID |
1000 | Container user ID (match host user: id -u) |
PGID |
1000 | Container group ID (match host user: id -g) |
TZ |
UTC | Container timezone |
IMAGE_TAG |
latest | Docker image tag (production compose only) |
DATA_PATH |
./data | Host path for persistent data (production compose) |
LOGS_PATH |
./logs | Host path for log files |
All backend variables listed above are also passable via docker-compose. See
docker-compose.yml for the full list with defaults.
Docker Compose Setup
Create .env file:
cat > .env << EOF
FLASHPOINT_HOST_PATH=/path/to/flashpoint
JWT_SECRET=$(openssl rand -hex 64)
DOMAIN=https://flashpoint.example.com
WEB_PORT=80
LOG_LEVEL=warn
EOF
Start services:
docker compose up -d
Environment Templates
Development (backend/.env):
NODE_ENV=development
FLASHPOINT_PATH=D:/Flashpoint
JWT_SECRET=development-secret-change-in-production
DOMAIN=http://localhost:5173
RATE_LIMIT_MAX_REQUESTS=1000
LOG_LEVEL=debug
Production (.env for Docker):
FLASHPOINT_HOST_PATH=/data/flashpoint
JWT_SECRET=CHANGE-THIS-TO-A-RANDOM-64-CHARACTER-STRING
DOMAIN=https://flashpoint.example.com
WEB_PORT=80
LOG_LEVEL=warn
Validation and Defaults
Required Variables:
Backend (local dev):
FLASHPOINT_PATH(only this is required; others auto-derive)
Docker Production:
FLASHPOINT_HOST_PATH(must point to Flashpoint installation)JWT_SECRET(must be changed from default)
Verify configuration:
cd backend
node -e "require('dotenv').config(); console.log(process.env.FLASHPOINT_PATH)"
Security Best Practices
- Never commit .env files to version control
- Use strong JWT secrets (64+ characters) in production
- Restrict CORS origins to your domain only (no wildcards)
- Use HTTPS in production (update DOMAIN to https://)
- Limit exposed ports (don't expose all services)
- Rotate secrets periodically
- Use environment-specific files (.env.production, .env.development)
- Store secrets in secure management system (AWS Secrets Manager, HashiCorp Vault)
- Use read-only mounts for Flashpoint data in Docker