Configuration

HappyView is configured via environment variables. A .env file in the project root is loaded automatically on startup. See Local Development for local setup, Docker for deploying from published images, or Production for the hardening checklist.

Environment variables

VariableRequiredDefaultDescription
DATABASE_URLyes---Database connection string. SQLite (sqlite://path/to/db?mode=rwc) or Postgres (postgres://user:pass@host/db)
DATABASE_BACKENDnoauto-detectedForce sqlite or postgres. Auto-detected from DATABASE_URL scheme if not set
SQLITE_JOURNAL_SIZE_LIMITno67108864 (64 MiB)Bytes. Caps how large the SQLite write-ahead log is allowed to grow before it's truncated back down after a checkpoint, bounding disk usage from WAL growth. SQLite-only; ignored on Postgres
PUBLIC_URLyes---Public-facing URL for HappyView (used for OAuth callbacks, e.g. https://happyview.example.com). For local development, use http://127.0.0.1:3000 — not localhost (see note below). Do not include the base path — see BASE_PATH
BASE_PATHno(none)Subpath prefix for mounting HappyView behind a reverse proxy (e.g. /hv). Must start with / and have no trailing slash. When set, all routes are served under this prefix and the dashboard is accessible at https://example.com/hv/. See Reverse proxy subpath
SESSION_SECRETnodev defaultSecret key for signing session cookies (at least 64 characters). Must be set in production
HOSTno0.0.0.0Bind host
PORTno3000Bind port
JETSTREAM_URLnowss://jetstream1.us-east.bsky.networkJetstream WebSocket URL for real-time record streaming
RELAY_URLnohttps://bsky.networkRelay URL for backfill repo discovery
PLC_URLnohttps://plc.directoryPLC directory URL for DID resolution
STATIC_DIRno./web/outDirectory containing the built dashboard static assets
EVENT_LOG_RETENTION_DAYSno30Number of days to keep event logs before automatic cleanup. Set to 0 to disable cleanup
TOKEN_ENCRYPTION_KEYno---Base64-encoded 32-byte key for encrypting stored OAuth tokens. Strongly recommended in production
DEFAULT_RATE_LIMIT_CAPACITYno100Default token bucket capacity used when registering a new API client
DEFAULT_RATE_LIMIT_REFILL_RATEno2.0Default token bucket refill rate (tokens/second) for new API clients
ATTESTATION_PRIVATE_KEYnoauto-generatedHex-encoded 32-byte secp256k1 private key for attestation signing. Auto-generated and persisted to database on first run
ATTESTATION_KEY_IDnodid:web:{host}#attestationKey identifier included in attestation signatures. Derived from PUBLIC_URL by default
ATTESTATION_SIG_TYPEnoapp-specific NSID$type value used in attestation signature objects
BACKFILL_CONCURRENT_PDSno10How many PDS servers to fetch from simultaneously during backfill. Overridden by database setting if set via admin API
BACKFILL_CONCURRENT_DIDS_PER_PDSno3How many repos to fetch concurrently from each PDS during backfill. Overridden by database setting if set via admin API
BACKFILL_CONCURRENT_RESOLUTIONno100How many DID document lookups to run in parallel during PDS resolution. Overridden by database setting if set via admin API
BACKFILL_RETENTION_DAYSno28Days to keep per-repo detail data from completed backfill jobs. 0 to keep indefinitely. Overridden by database setting if set via admin API
BACKFILL_DATABASE_MAX_CONNECTIONSnoauto-calculatedOverride the backfill connection pool size. Auto-calculated from concurrency settings if not set
VERBOSE_EVENT_LOGGINGnofalseLog every record index, hook execution, and hook skip to the event log. High write volume — recommended only for debugging. Overridden by database setting if set via admin API
RUST_LOGnohappyview=debug,tower_http=debug,sqlx=warnLog filter (uses tracing_subscriber::EnvFilter)
APP_NAMEno---Application name shown on OAuth authorization screens. Overridden by database setting if set via admin API
LOGO_URIno---URL to application logo for OAuth screens. Overridden by database setting or logo upload
TOS_URIno---URL to terms of service. Overridden by database setting if set via admin API
POLICY_URIno---URL to privacy policy. Overridden by database setting if set via admin API

Example .env

# SQLite (default — zero setup required)
DATABASE_URL=sqlite://data/happyview.db?mode=rwc
PUBLIC_URL=http://127.0.0.1:3000
SESSION_SECRET=change-me-in-production

# Or use Postgres instead:
# DATABASE_URL=postgres://happyview:happyview@localhost/happyview

# Optional overrides
# BASE_PATH=/hv
# HOST=0.0.0.0
# PORT=3000
# SQLITE_JOURNAL_SIZE_LIMIT=67108864
# JETSTREAM_URL=wss://jetstream1.us-east.bsky.network
# RELAY_URL=https://bsky.network
# PLC_URL=https://plc.directory
# STATIC_DIR=./web/out
# EVENT_LOG_RETENTION_DAYS=30
# TOKEN_ENCRYPTION_KEY=base64-encoded-32-byte-key
# DEFAULT_RATE_LIMIT_CAPACITY=100
# DEFAULT_RATE_LIMIT_REFILL_RATE=2.0
# BACKFILL_CONCURRENT_PDS=10
# BACKFILL_CONCURRENT_DIDS_PER_PDS=3
# BACKFILL_CONCURRENT_RESOLUTION=100
# BACKFILL_RETENTION_DAYS=28
# VERBOSE_EVENT_LOGGING=false
# RUST_LOG=happyview=debug,tower_http=debug,sqlx=warn
# APP_NAME=My App
# LOGO_URI=https://example.com/logo.png
# TOS_URI=https://example.com/tos
# POLICY_URI=https://example.com/privacy

Next steps