Skip to content

Configuration

Everything is configured through environment variables (loaded from a single .env in the Docker Compose setup). The hub can alternatively read its entire config from a YAML file. See Optional: YAML config.

Defaults below are the hub's built-in defaults. Empty cells mean there is no default (the feature is off or the value is required).

Common (both roles)

VarDefaultPurpose
LOG_LEVELinfoLog verbosity. Applies to both the hub and agents.
TZUTCTimezone. Applies to both the hub and agents.
HUB_IMAGEghcr.io/buco7854/bloodpoint-incentives/hub:latestHub image used by Compose. Override for a fork or pinned tag.
AGENT_IMAGEghcr.io/buco7854/bloodpoint-incentives/agent:latestAgent image used by Compose. Override for a fork or pinned tag.

Hub

Core

VarDefaultPurpose
PORT3000HTTP port the hub listens on (clamped to 1–65535).
STALE_AFTER_SECONDS900A region's reading is shown as stale once older than this many seconds (minimum 60).
PAGE_SIZE20Paginate region lists above this count.
DB_PATH./data/bloodpoint.dbSQLite database for readings + history. Persist it on a volume.
DATA_RETENTION_DAYS31Days of readings to keep before pruning (minimum 1, raise to e.g. 365).
FORECAST_WINDOW_DAYS84Days of history the bonus forecast trains on, independent of retention (minimum 1).
CONTACT_EMAILEmail shown on the contribute page and footer.
CONTRIBUTE_ENABLEDfalseShow the "contribute data" page, banner, and nav.
AGENT_SETUP_URLhttps://docs.bpincentives.com/guide/running-an-agentWhere the contribute page points for agent setup.
DISCORD_URLCommunity link shown next to the contact email.
MATRIX_URLCommunity link shown next to the contact email.
TRUSTED_PROXIESfalseWhich upstreams may set the real client IP via X-Forwarded-For / X-Real-IP (used for the live viewer count). An IP/CIDR list, true/false, or a hop count. Untrusted callers can't spoof their IP. Behind a reverse proxy, set this or every viewer collapses to the proxy's IP.
CORS_ALLOWED_ORIGINSBrowser origins allowed to call the API cross-origin (comma-separated), e.g. https://docs.bpincentives.com for the docs site's interactive "Try it". Use * to allow any (without credentials). Unset means same-origin only.
HUB_CONFIGPath to a YAML config carrying the full hub config (env overrides it). See below.

Cadence

VarDefaultPurpose
POLL_MIN_SECONDS%refreshTime%Default minimum poll interval handed to agents. A number of seconds or a %refreshTime% expression. Floored at 300s.
POLL_MAX_SECONDSmin × 1.33Default maximum poll interval. A number of seconds or a %refreshTime% expression. Defaults to the min times the default ratio if omitted.

%refreshTime% (alias %auto%) resolves to Dead by Daylight's live refresh cadence, learned from agent reports. Until a value is known, the hub uses a 300-second bootstrap interval. Expressions like %refreshTime% * 1.33 are allowed. See How it works.

Auth (see Authentication)

VarDefaultPurpose
SESSION_SECRETSigns session cookies. If unset, an ephemeral secret is generated and sessions reset on restart.
ORIGINhttp://localhost:<PORT>Public origin. Required for WebAuthn passkeys.
RP_IDORIGIN's hostWebAuthn relying-party id (the passkey domain).
RP_NAMEBloodpoint IncentivesWebAuthn relying-party display name, shown in the passkey prompt.
COOKIE_SECUREtrue if ORIGIN is httpsMark session cookies Secure.
SESSION_TTL_HOURS168Session lifetime in hours (minimum 1).
REQUIRE_AUTHfalseRequire a logged-in session (or API key) to view the whole site.
ENABLE_API_KEYSfalseLet users mint personal API keys that authenticate as their owner. See API keys.
ADMIN_BOOTSTRAP_USERSeed the first admin's username (else use the /setup page).
ADMIN_BOOTSTRAP_PASSWORDSeed the first admin's password. Required if ADMIN_BOOTSTRAP_USER is set.
ADMIN_BOOTSTRAP_EMAILOptional email for the seeded admin.
ADMIN_BOOTSTRAP_NAMEOptional display name for the seeded admin.

Agent provisioning (hub side)

VarDefaultPurpose
PROVISION_AGENTSRegister agents declaratively: comma-separated <id>:<token>:<region>:<provider> entries, upserted by <id> on boot.
AGENTn_TOKENToken for numbered agent n. Blank = skip provisioning (add it in the admin UI). Compose interpolates the same value into the agent container.
AGENTn_REGIONRegion agent n covers, e.g. eu-central-1.
AGENTn_PROVIDERAuth provider for agent n (decides the platform). steam today.
AGENTn_IDagent-nStable provision id for agent n (used for upsert).
AGENTn_LABELOptional human label for agent n.

Agents can also be registered at runtime in the admin UI, so none of the agent env vars are strictly required at boot.

Agent

VarDefaultPurpose
HUB_URL– (required)Base URL of the hub to report to. Compose injects http://hub:3000.
AGENT_KEY– (required)The agent's token. The hub maps it to a region+platform.
AUTH_PROVIDERsteamProvider the agent authenticates with (decides its platform). Only steam today.
AGENT_HEALTH_PORT3001Port for the minimal health endpoint (0 disables it).
STEAM_USERNAME– (required)Steam account for headless login + depot discovery. Must own Dead by Daylight.
STEAM_PASSWORD– (required)Steam account password.
STEAM_SHARED_SECRETSteam Guard shared secret (base64) for unattended 2FA. Strongly recommended for always-on agents.
DBD_API_KEYFallback (not recommended): a pre-obtained key for DBD auth, used only if the Steam login is rejected. The key expires and cannot self-refresh.
VERSION_REFRESH_HOURS6How often the agent re-resolves the latest build / client version.
AGENT_MIN_POLL_SECONDS%refreshTime%Accepted-range floor: refuse if the hub asks to poll faster. Seconds or a %refreshTime% expression. off/none disables it.
AGENT_MAX_POLL_SECONDS%refreshTime% * 1.33Accepted-range ceiling: refuse if the hub asks to poll slower. Seconds or a %refreshTime% expression. off/none disables it.
STATE_DIR./dataDirectory for the last-working-version state file.

The poll cadence itself is set by the hub, not the agent. The agent only enforces its accepted range. The client version and OS headers are not configurable. The client version is discovered live and the OS header is fixed.

Optional: YAML config

Point HUB_CONFIG at a YAML file to define the whole hub there: settings, cadence, the provision: agent list, and an auth: block. See hub.example.yaml in the repo. The file supports ${ENV} interpolation (including ${VAR:-default}), and any matching environment variable overrides the file, so the file is the baseline and env is the override. Keep secrets as ${VAR} so they live in the environment, not the file.

yaml
port: 3000 # overridden by PORT if set
contactEmail: ${CONTACT_EMAIL:-}
poll: { min: "%refreshTime%", max: "%refreshTime% * 1.33" }
auth:
  origin: ${ORIGIN:-}
  sessionSecret: ${SESSION_SECRET:-}
  requireAuth: false
provision:
  - { id: eu-1, token: "${AGENT_EU_1_TOKEN}", region: eu-central-1, provider: steam }
  - { id: us-1, token: "${AGENT_US_1_TOKEN}", region: us-east-1, provider: steam }

A note on quoting secrets

WARNING

Do not wrap values in quotes in env files. Some setups pass the quotes through literally and corrupt the value. Surrounding quotes are stripped defensively, but the cleaner habit is to leave them off.