Skip to content

Running the hub

The hub is the only piece the browser talks to: it aggregates readings, persists history, serves the React dashboard, the REST API, the interactive API docs, and the live stream. This page walks through running it with Docker Compose.

Prerequisites

  • Docker with the Compose plugin.
  • At least one agent token + Steam account if you want live data right away (you can also add agents later from the admin UI). See Running an agent.

Images

The hub and agent are separate images, both published to GHCR:

  • Hub: ghcr.io/buco7854/bloodpoint-incentives/hub:latest
  • Agent: ghcr.io/buco7854/bloodpoint-incentives/agent:latest

Compose pulls these by default. You can override them with HUB_IMAGE / AGENT_IMAGE in your .env (for a fork or a pinned tag). The hub image is the static Go binary that serves the SPA. The agent image is the Node runtime with the Steam libraries.

Walkthrough

A single .env file drives everything. Copy the example and edit it:

bash
cp .env.example .env

The shipped docker-compose.yml defines a hub service, a hub-data volume, and one agent service (agent-1):

yaml
services:
  hub:
    image: ${HUB_IMAGE:-ghcr.io/buco7854/bloodpoint-incentives/hub:latest}
    container_name: bloodpoint-hub
    restart: unless-stopped
    ports:
      - '${PORT:-3000}:${PORT:-3000}'
    env_file: .env
    volumes:
      - hub-data:/app/data
      # - ./hub.yaml:/config/hub.yaml:ro

volumes:
  hub-data:
  agent-1-data:

A few things to note:

  • env_file: .env: every variable in your .env reaches the hub container. This is also where compose reads the AGENTn_* variables and interpolates the same ${AGENT1_TOKEN} into both the hub's PROVISION_AGENTS and the agent container, so each token is declared once.
  • hub-data:/app/data: the SQLite database (DB_PATH, default ./data/bloodpoint.db) lives here. Keep it on a volume so your readings and history persist across restarts and upgrades.
  • The commented ./hub.yaml:/config/hub.yaml:ro mount is for the optional YAML config (see below).

Bring it up:

bash
docker compose up -d   # pulls the published hub + agent images

The hub comes up on http://localhost:3000. It serves the SPA at /, the interactive API docs at /docs, and the OpenAPI spec at /openapi.json.

First run: creating the first admin

On first run the hub has no admin account. There are two ways to create one:

  1. The /setup page: open http://localhost:3000/setup and create the first admin interactively. This page only works while there is no admin yet.
  2. Bootstrap from env: set ADMIN_BOOTSTRAP_USER and ADMIN_BOOTSTRAP_PASSWORD (optionally ADMIN_BOOTSTRAP_EMAIL / ADMIN_BOOTSTRAP_NAME) before first boot to seed the admin without the setup page.

TIP

If MFA is enforced for admins (the default), the first admin enrolls a second factor on first login. See Authentication.

Gating the site

By default the dashboard and read API are public. To require a logged-in session to view the whole site, set:

bash
REQUIRE_AUTH=true

The /healthz endpoint and the /api/v1/agent/* ingest routes (which use per-agent token auth) stay exempt. When the gate is on, read endpoints accept a session or an API key.

Optional: full config in YAML

Instead of a long .env, you can point HUB_CONFIG at a YAML file carrying the entire hub config: settings, cadence, the provision: agent list, and an auth: block. See hub.example.yaml in the repo. The file supports ${ENV} interpolation, 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 stay in the environment, not in the file.

Uncomment the volume mount and set HUB_CONFIG:

yaml
volumes:
  - hub-data:/app/data
  - ./hub.yaml:/config/hub.yaml:ro
bash
HUB_CONFIG=/config/hub.yaml

Building the images yourself

The repo's Dockerfile has a hub and an agent target:

bash
docker build --target hub   -t bp-hub   .
docker build --target agent -t bp-agent .

Next steps