Skip to content

Configuration Reference

Doug edited this page Aug 8, 2026 · 3 revisions

Configuration Reference

All configuration is via environment variables in .env (copy from .env.template, which documents every option inline). This page is the map: what each group is for, and which variables actually block startup.

Source of truth: .env.template. Lines marked [REQUIRED] must be set; [optional] ones disable their feature when blank. Never commit .env.

Must be set or the app won't run

Variable Why
DB_PASSWORD / POSTGRES_PASSWORD Postgres auth. The shipped compose stack reads DB_PASSWORD (it builds DATABASE_URL and sets the db service's password from it); POSTGRES_PASSWORD is what the template names for non-compose setups.
JWT_SECRET (≥32 bytes) or RS_PRIVATE_KEY/RS_PUBLIC_KEY JWT signing. The app refuses to start with no signing key. RS256 preferred; HS256 JWT_SECRET is the fallback.
MASTER_ENCRYPTION_KEY (Fernet key) Encrypts secrets at rest (integration tokens, webhook secrets, customer PII). Not tagged [REQUIRED] in the template, but the app refuses to boot in production-like envs without it.
SECRET_KEY FastAPI session/CSRF signing.

Generate keys: openssl rand -hex 32 (JWT_SECRET / SECRET_KEY) and python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" (MASTER_ENCRYPTION_KEY, GDX_FERNET_KEY).

Wired by Docker Compose (don't usually touch)

DATABASE_URL, CONTROL_DATABASE_URL, and REDIS_URL are set by docker-compose.yml to point at the db and redis services. Override only if you run external Postgres/Redis.

Public URLs & webhooks

  • GDX_PUBLIC_BASE_URL — the instance's public origin (e.g. https://app.example.com). Used for CORS, server-built absolute links, the advertised MCP resource URL, and Outlook/Graph webhook subscriptions — which fail to create without it. Set it on any internet-facing install.
  • CUSTOMER_PORTAL_BASE_URL — base URL for customer-portal magic-link/invite emails.
  • TENANT_BASE_DOMAIN — fallback domain used to build Outlook and Phone.com callback/webhook URLs when GDX_PUBLIC_BASE_URL isn't the right shape for your setup.

First-run identity

  • GDX_ADMIN_EMAIL / GDX_ADMIN_PASSWORD — the seeded admin (password optional; a random one is logged on first boot if blank).
  • GDX_TENANT_ID / GDX_TENANT_SLUG / GDX_TENANT_NAME — the single tenant the app pins every request to.
  • APP_VERSION — the running release tag (drives /health and update-check).

Integrations — all optional, blank = disabled

Each group lights up a feature when filled in; leaving it blank turns the feature off (or makes it fail-open in dev). See .env.template for the exact keys.

Group Enables
Stripe (STRIPE_*) Billing, payments, Connect, subscription tiers.
QuickBooks (QB_*) QBO accounting sync (OAuth + webhooks).
Google (GOOGLE_MAPS_API_KEY, GOOGLE_SSO_*) Maps/routing/geocoding; Google login.
Microsoft SSO (MICROSOFT_SSO_*) Azure AD login.
Twilio (TWILIO_*) SMS.
Email (PLATFORM_SMTP_*, SMTP_*) Outbound mail (signup, password reset, tenant SMTP).
AI / LLM (AI_PROVIDER_URL / AI_PROVIDER_MODEL / AI_PROVIDER_KEY) AI estimates and message drafts, against any OpenAI-compatible endpoint (local vLLM/Ollama works). OPENAI_API_KEY is used only for voice transcription.
Sentry (SENTRY_*) Error tracking.
Cloudflare (CLOUDFLARE_*, TURNSTILE_*) Cache purge / DNS; bot challenge on public lead intake.
Web Push (VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY) Push notifications to installed mobile/PWA devices; unset = push silently disabled (the app hides the enable button).
Bank Feeds (BANK_FEEDS_REDIRECT_URI) Overrides the Banno OAuth callback URL when the default built from the public base URL isn't right.

Notes

  • GDX_ENV = production | development | testing — relaxes some prod-only guards (e.g. encryption-key enforcement) in dev.
  • PLANNER_DIGEST_EMAIL / PLANNER_DIGEST_HOUR — daily email digest of open planner tasks: the recipient (unset = digest off) and the send hour in UTC (default 13).
  • LOG_LEVEL, LOG_SHIP_TARGET, LOG_RETENTION_DAYS — logging behavior.
  • Many integration vars only matter for features you use — start minimal (the "must be set" table above) and add groups as you turn features on.

See also

Clone this wiki locally