Skip to content

Environment Configuration Guide

This document details all environment variables used by CampaignBrain App (cbapp). Copy .env.example to .env and configure for your deployment.


Table of Contents

  1. Quick Start
  2. Application Identity
  3. Server Configuration
  4. URLs
  5. Database
  6. Branding & Theme
  7. AI / LLM Services
  8. External Service Integrations
  9. External Key Generation

Quick Start

# Copy example file
cp .env.example .env

# Generate required secrets
python -c "import secrets; print('SECRET_KEY=' + secrets.token_hex(32))"
python -c "import secrets; print('API_KEYS=' + secrets.token_hex(16))"

# Edit .env with your values
nano .env

Minimum Required Variables

Variable Description
SECRET_KEY JWT signing key (generate securely)
DB_PATH Path to DuckDB database
FRONTEND_URL Public URL of your deployment
BACKEND_API_URL Internal API URL

Application Identity

Variable Required Default Description
APP_NAME No Pocket Field Kit Display name in UI header
APP_NAME_SHORT No PFK Short name (max 10 chars)
PROJECT_NAME No - Internal identifier (lowercase)
ADMIN_EMAIL No - Admin contact email
DEBUG No true Enable debug mode

Example:

APP_NAME="Smith for Senate"
APP_NAME_SHORT="S4S"
PROJECT_NAME="smith2026"
DEBUG=false


Server Configuration

Variable Required Default Description
FRONTEND_HOST No 0.0.0.0 Frontend bind address
FRONTEND_PORT No 8080 Frontend port
BACKEND_HOST No 0.0.0.0 Backend bind address
BACKEND_PORT No 8000 Backend API port
SECRET_KEY Yes - JWT secret (32+ hex chars)
SESSION_INACTIVITY_TIMEOUT_MINUTES No 10 Minutes before session warning
SESSION_WARNING_COUNTDOWN_SECONDS No 60 Seconds in warning countdown

Generating SECRET_KEY

# Python
python -c "import secrets; print(secrets.token_hex(32))"

# OpenSSL
openssl rand -hex 32

Example:

FRONTEND_PORT=32300
BACKEND_PORT=32301
SECRET_KEY="a1b2c3d4e5f6..."


URLs

Variable Required Default Description
FRONTEND_URL Yes http://localhost:31313 Public frontend URL
BACKEND_API_URL Yes http://localhost:8000/api Backend API URL (internal)
API_BASE_URL No /api Frontend API proxy path
WS_BASE_URL No - WebSocket URL for real-time

Example:

FRONTEND_URL="https://campaign.example.com"
BACKEND_API_URL="http://localhost:8000/api"
API_BASE_URL="/api"
WS_BASE_URL="wss://campaign.example.com"


Database

Variable Required Default Description
DB_PATH No db/pocket.db DuckDB database file path

The database is automatically created on first run. Path is relative to project root.

Example:

DB_PATH="db/mycampaign.duckdb"


Branding & Theme

Logo Paths

Variable Default Description
APP_LOGO_NAME /static/images/logo-name.png Logo with text
APP_LOGO_ICON /static/images/logo-icon.png Square icon
APP_LOGO_CROPPED /static/images/logo-cropped.png Cropped version
APP_LOGO_FULL /static/images/logo-full.png Full logo
APP_LOGO_MOBILE /static/images/logo-mobile.svg Mobile-optimized

Theme Colors

Variable Default Description
THEME_PRIMARY_COLOR #0e173e Primary brand color
THEME_SECONDARY_COLOR #f1c613 Secondary accent
THEME_ACCENT_COLOR #f1c613 Highlight color
THEME_TEXT_COLOR #374151 Main text color
THEME_SIDEBAR_COLOR #f8fafc Sidebar background

Example:

THEME_PRIMARY_COLOR="#1e40af"
THEME_SECONDARY_COLOR="#fbbf24"


AI / LLM Services

Ollama (Local LLM)

Variable Default Description
OLLAMA_BASE_URL http://localhost:11434 Ollama server URL
OLLAMA_EMBED_MODEL nomic-embed-text:latest Embedding model
OLLAMA_LLM_MODEL gemma3:12b Chat/completion model

Setup:

# Install Ollama
curl -fsSL https://ollama.com/install.sh | sh

# Pull required models
ollama pull nomic-embed-text:latest
ollama pull gemma3:12b

Anthropic (Claude)

Variable Required Default Description
ANTHROPIC_API_KEY For chat - Anthropic API key
CB_CHAT_MODEL No claude-sonnet-4-20250514 Claude model

Get API Key: https://console.anthropic.com/


External Service Integrations

Service-to-Service Auth

Variable Description
API_KEYS Comma-separated API keys for external callers

Used by tenant manager and other services to authenticate API calls.

# Generate a key
python -c "import secrets; print(secrets.token_hex(16))"

Example:

API_KEYS="key1abc123,key2def456"

i360 Voter Data

Variable Default Description
ENABLE_I360_LINKS false Enable voter profile links
I360_BASE_URL https://www.i360portal.com i360 portal URL
I360_VOTER_URL_TEMPLATE {base_url}/voter/{svid} Profile URL template

YASP Survey Platform

Variable Default Description
YASP_BASE_URL https://surveys.nominate.ai/api/v1 YASP API URL
YASP_API_KEY - YASP authentication key

CBFiles File Storage

Variable Default Description
FILES_BASE_URL https://files.nominate.ai/api/v1 CBFiles API URL
FILES_API_KEY - CBFiles authentication key
FILES_TENANT_BUCKET - Bucket name (usually = PROJECT_NAME)

OpenStreetMap OAuth

Variable Description
OSM_CLIENT_ID OAuth client ID
OSM_CLIENT_SECRET OAuth client secret
OSM_REDIRECT_URI OAuth callback URL

Register: https://www.openstreetmap.org/oauth2/applications


External Key Generation

1. SECRET_KEY (Required)

Internal JWT signing key. Never share or commit.

python -c "import secrets; print(secrets.token_hex(32))"

2. API_KEYS (Required for external integrations)

Keys for tenant manager and other services to call cbapp API.

python -c "import secrets; print(secrets.token_hex(16))"

3. ANTHROPIC_API_KEY (For AI Chat)

  1. Go to https://console.anthropic.com/
  2. Sign up or log in
  3. Navigate to API Keys
  4. Create a new key
  5. Copy the key (shown only once)

4. YASP_API_KEY (For Surveys)

Contact your YASP administrator or:

# If you have YASP admin access via CLI
python -m yasp.cli create-api-key --name "cbapp-{tenant}"

5. FILES_API_KEY (For File Storage)

Step 1: Bootstrap admin user (first time only)

# On the CBFiles server
python -m cbfiles.cli bootstrap \
  --name "Tenant Admin" \
  --email "admin@yourdomain.com"

# Save the returned API key!

Step 2: Create service key via API

# Using the bootstrap key
curl -X POST "https://files.nominate.ai/api/v1/users/me/keys" \
  -H "X-API-Key: YOUR_BOOTSTRAP_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "cbapp-mytenant"}'

Step 3: Create tenant bucket

curl -X POST "https://files.nominate.ai/api/v1/buckets" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "mytenant"}'

6. OSM OAuth Credentials (For Map Features)

  1. Go to https://www.openstreetmap.org/oauth2/applications
  2. Log in with your OSM account
  3. Click "Register new application"
  4. Fill in:
  5. Name: "CampaignBrain - {Your Campaign}"
  6. Redirect URI: https://your-domain.com/api/osm/callback
  7. Permissions: Select required scopes
  8. Save Client ID and Client Secret

Environment by Deployment Type

Development

DEBUG=true
FRONTEND_URL="http://localhost:8080"
BACKEND_API_URL="http://localhost:8000/api"
SECRET_KEY="dev-only-not-for-production"

Production

DEBUG=false
FRONTEND_URL="https://campaign.example.com"
BACKEND_API_URL="http://localhost:8000/api"
SECRET_KEY="<generate-secure-64-char-key>"

Docker

FRONTEND_HOST=0.0.0.0
BACKEND_HOST=0.0.0.0
DB_PATH="/data/db/campaign.duckdb"
OLLAMA_BASE_URL="http://ollama:11434"

Troubleshooting

"Invalid token" errors

  • Check SECRET_KEY is set and consistent across restarts
  • Ensure frontend and backend use the same key

"Connection refused" to backend

  • Verify BACKEND_API_URL is correct
  • Check backend is running on specified port

Files module 401 errors

  • Verify FILES_API_KEY is set
  • Check key has not expired
  • Ensure FILES_TENANT_BUCKET matches your bucket

Surveys not loading

  • Check YASP_API_KEY is valid
  • Verify YASP_BASE_URL is accessible

Chat not working

  • Verify ANTHROPIC_API_KEY is set
  • Check API key has available credits