Installation
Requirements
- Node.js 24.x (LTS)
- npm 11+
- Docker Engine >= 20.10
- Docker Compose v2 (
docker compose) - Git
- Optional: Python 3.8+ and Ansible for kiosk appliance setup
Get the code
bash
git clone https://github.com/CameronBrooks11/freeboard.git
cd freeboard
git checkout main
# Optional: align to repo Node baseline via .nvmrc
nvm use || nvm install
npm installEnvironment setup
Copy .env.example to .env and set real secrets.
For quick local development bootstrap, copy .env.dev to .env first.
Minimum production-safe values
bash
# API runtime
FREEBOARD_RUNTIME_ENV=production
JWT_SECRET=replace-with-a-long-random-secret-at-least-32-chars
JWT_GATEWAY_SECRET=replace-with-a-long-random-gateway-secret-at-least-32-chars
GATEWAY_SERVICE_TOKEN=replace-with-a-long-random-gateway-service-token-at-least-32-chars
CREDENTIAL_ENCRYPTION_KEY=replace-with-base64-32-byte-key
# Optional runtime image tag pinning (default is latest)
FREEBOARD_UI_IMAGE_TAG=latest
FREEBOARD_API_IMAGE_TAG=latest
FREEBOARD_GATEWAY_IMAGE_TAG=latest
# Postgres for API (default runtime)
FREEBOARD_POSTGRES_URL=postgresql://postgres:replace-with-strong-password@postgres:5432/freeboard
# Postgres init credentials (docker-compose.postgres.yml)
POSTGRES_USER=postgres
POSTGRES_PASSWORD=replace-with-strong-postgres-password
POSTGRES_DB=freeboard
# Gateway egress allowlist (required in non-development runtime)
EGRESS_ALLOWED_HOSTS=api.open-meteo.com,api.coingecko.comSecret storage/rotation patterns and incident response are documented in:
Optional local bootstrap admin
bash
CREATE_ADMIN=true
ADMIN_EMAIL=admin@example.local
ADMIN_PASSWORD=ChangeMe123!After first successful login, set CREATE_ADMIN=false.
Local development
cp .env.dev .env- Set bootstrap credentials if needed (
CREATE_ADMIN=true) - Run
npm run dev - Login once and disable bootstrap (
CREATE_ADMIN=false)
API env precedence:
- Process environment (shell/CI)
packages/api/.env(optional local override)- Repo root
.env - API defaults
Run with Docker Compose
bash
docker compose -f docker-compose.yml -f docker-compose.postgres.yml up -dPinning examples:
bash
# release pin
FREEBOARD_UI_IMAGE_TAG=v0.1.0
FREEBOARD_API_IMAGE_TAG=v0.1.0
FREEBOARD_GATEWAY_IMAGE_TAG=v0.1.0
# immutable build pin
FREEBOARD_UI_IMAGE_TAG=sha-abc1234
FREEBOARD_API_IMAGE_TAG=sha-abc1234
FREEBOARD_GATEWAY_IMAGE_TAG=sha-abc1234Rollback is tag-based: switch to the prior known-good v* or sha-* tags and redeploy.
Services:
- UI:
http://localhost:8080 - API (via UI reverse proxy):
http://localhost:8080/graphql(internal:freeboard-api:4001) - Gateway (via UI reverse proxy):
http://localhost:8080/gateway/http/fetch(internal:freeboard-gateway:8001)
Security checks before go-live
- Keep
FREEBOARD_RUNTIME_ENV=production - Use strong
JWT_SECRET(32+ chars) - Use strong
JWT_GATEWAY_SECRETandGATEWAY_SERVICE_TOKEN - Set valid
CREDENTIAL_ENCRYPTION_KEY(base64 32-byte key) - Keep
EGRESS_ALLOW_INSECURE_TLS=false - Keep
EGRESS_ALLOW_PRIVATE_DESTINATIONS=false - Set strict
EGRESS_ALLOWED_HOSTS - Set
API_TRUST_PROXY_HOPSandREALTIME_TRUST_PROXY_HOPScorrectly for your reverse-proxy topology - Keep
SECURITY_LIMITER_BACKENDaligned withDB_BACKENDandSECURITY_LIMITER_FAILURE_MODE=fail-closedin non-dev runtime - Keep
REALTIME_LIMITER_FAILURE_MODE=fail-closedunless degraded-mode fail-open is intentionally approved - Keep
CREATE_ADMIN=falseafter bootstrap - Use non-default Postgres credentials
- Follow Secrets Operations Runbook for setup/rotation/incident workflow
Security Rollout Runbook
For security-control changes (proxy trust headers/hops, limiter backend/failure-mode policy, gateway realtime limiter behavior), use:
This runbook defines staged deploy order (proxy -> API -> gateway), canary watch metrics, and rollback steps.
Release Readiness Runbook
For final PostgreSQL release hardening and pre-release checklist signoff, use: