Files
the-collective-hub/docs/04-environment-variables.md

7.4 KiB

Environment Variables Document — The Collective Hub

Overview

Environment variables are the only difference between deployments. Each Coolify deployment has its own set of env vars, but all deployments share the same database, CDN, and Discord OAuth app.


Variable Reference

Required for Every Deployment

Variable Example Description Shared or Per-Site?
SITE_SLUG bad-movies-theater Identifies which site this deployment serves. Must match a slug in the sites table. Per-site
PUBLIC_SITE_URL https://badmovies.example.com The public URL of this deployment. Used for auth callbacks, canonical URLs. Per-site
DATABASE_URL postgresql://user:pass@host:5432/collective_hub Postgres connection string. Shared (same for all)
BETTER_AUTH_SECRET (generated) Secret key for Better Auth session signing. Shared (same for all)
BETTER_AUTH_URL https://badmovies.example.com Base URL for auth callbacks. Must match PUBLIC_SITE_URL. Per-site
DISCORD_CLIENT_ID 123456789012345678 Discord OAuth application client ID. Shared
DISCORD_CLIENT_SECRET abc123... Discord OAuth application client secret. Shared
OWNER_DISCORD_ID 123456789012345678 Discord user ID of the site owner. Used to bootstrap ownership on first login. Per-site

Required for CDN (Phase 1)

Variable Example Description Shared or Per-Site?
CDN_BASE_URL https://cdn.example.com Base URL for constructing CDN URLs. Shared
CDN_STORAGE_ENDPOINT https://ny.storage.bunnycdn.com Storage API endpoint. Shared
CDN_ACCESS_KEY abc123... Storage access key. Shared
CDN_SECRET_KEY (S3 only) Secret key for S3-compatible storage. Shared
CDN_BUCKET collective-hub Bucket or storage zone name. Shared
CDN_REGION us-east-1 Region for S3-compatible storage. Shared

Super Admin

Variable Example Description Shared or Per-Site?
SUPER_ADMIN_DISCORD_IDS 123456789,987654321 Comma-separated Discord user IDs with cross-site super admin access. Shared

Migration Control

Variable Example Description Shared or Per-Site?
RUN_MIGRATIONS true Whether this deployment should run database migrations on startup. Only one deployment should have this set to true. Per-site (only one true)

Optional

Variable Example Description Shared or Per-Site?
NODE_ENV production Node environment. Per-site (usually production)
LOG_LEVEL info Logging verbosity. Per-site
FEATURE_FLAGS events:on Comma-separated feature flags (future). Per-site

Example: Full Deployment Env File

Deployment: bad-movies-theater (primary — runs migrations)

# Site Identity
SITE_SLUG=bad-movies-theater
PUBLIC_SITE_URL=https://badmovies.example.com

# Database (shared)
DATABASE_URL=postgresql://hub_app:password@db.example.com:5432/collective_hub

# Auth (Better Auth)
BETTER_AUTH_SECRET=generated-secret-value-here
BETTER_AUTH_URL=https://badmovies.example.com

# Discord OAuth (shared)
DISCORD_CLIENT_ID=123456789012345678
DISCORD_CLIENT_SECRET=your-discord-client-secret

# Ownership Bootstrap
OWNER_DISCORD_ID=123456789012345678

# Super Admin
SUPER_ADMIN_DISCORD_IDS=111111111111111111

# Migration Control
RUN_MIGRATIONS=true

# CDN (shared)
CDN_BASE_URL=https://cdn.example.com
CDN_STORAGE_ENDPOINT=https://ny.storage.bunnycdn.com
CDN_ACCESS_KEY=your-bunny-access-key
CDN_BUCKET=collective-hub

# Optional
NODE_ENV=production
LOG_LEVEL=info

Deployment: garbage-day (secondary — skips migrations)

# Site Identity
SITE_SLUG=garbage-day
PUBLIC_SITE_URL=https://garbageday.example.com

# Database (shared — same value)
DATABASE_URL=postgresql://hub_app:password@db.example.com:5432/collective_hub

# Auth (Better Auth)
BETTER_AUTH_SECRET=generated-secret-value-here
BETTER_AUTH_URL=https://garbageday.example.com

# Discord OAuth (shared — same value)
DISCORD_CLIENT_ID=123456789012345678
DISCORD_CLIENT_SECRET=your-discord-client-secret

# Ownership Bootstrap
OWNER_DISCORD_ID=987654321098765432

# Super Admin (same value)
SUPER_ADMIN_DISCORD_IDS=111111111111111111

# Migration Control
RUN_MIGRATIONS=false

# CDN (shared — same values)
CDN_BASE_URL=https://cdn.example.com
CDN_STORAGE_ENDPOINT=https://ny.storage.bunnycdn.com
CDN_ACCESS_KEY=your-bunny-access-key
CDN_BUCKET=collective-hub

# Optional
NODE_ENV=production
LOG_LEVEL=info

What's Shared vs Per-Site

Shared across ALL deployments:
├── DATABASE_URL              (one database)
├── BETTER_AUTH_SECRET        (same session signing key)
├── DISCORD_CLIENT_ID         (one Discord OAuth app)
├── DISCORD_CLIENT_SECRET
├── SUPER_ADMIN_DISCORD_IDS   (system maintainers)
├── CDN_BASE_URL              (one CDN bucket)
├── CDN_STORAGE_ENDPOINT
├── CDN_ACCESS_KEY
├── CDN_SECRET_KEY (if S3)
├── CDN_BUCKET
└── CDN_REGION (if S3)

Unique per deployment:
├── SITE_SLUG                 (which site this is)
├── PUBLIC_SITE_URL           (its domain)
├── BETTER_AUTH_URL           (must match PUBLIC_SITE_URL)
├── OWNER_DISCORD_ID          (who owns this site)
└── RUN_MIGRATIONS            (only one deployment = true)

Notes & Warnings

Discord OAuth: Shared App

All sites share one Discord OAuth application. This means:

  • Users see the same app name when authorizing (e.g., "The Collective Hub")
  • The OAuth redirect URL list must include every site's callback URL
  • Discord has a limit on redirect URLs — manageable for a handful of sites
  • If the system grows to many sites, each site may need its own Discord OAuth app, or a central auth domain pattern should be introduced

Better Auth Secret

BETTER_AUTH_SECRET must be the same across all deployments because sessions are signed with it. This enables super admins to potentially navigate between site admin panels with a single session (future enhancement).

Database Migrations — Automated but Coordinated

Migrations run automatically on app startup, but only on the deployment with RUN_MIGRATIONS=true. All other deployments skip migrations (RUN_MIGRATIONS=false). This means:

  • Exactly one deployment is designated as the migration runner
  • That deployment must be deployed first when schema changes are made
  • If the migration runner is down, other deployments still work (they just can't run new migrations)
  • Choose a stable, low-traffic deployment as the migration runner (or the super admin dashboard deployment)

Super Admin Access

SUPER_ADMIN_DISCORD_IDS is a comma-separated list of Discord user IDs. Users matching these IDs bypass site-scoped membership checks and can access any site's admin panel. This is intended for David (system maintainer) and should be kept to a minimal, trusted set of IDs.

Sensitive Values

All secrets (database URL, auth secrets, Discord secrets, CDN keys) must be stored securely in Coolify's environment variable management — never committed to the repository.