# ----------------------------------------------------------------------------- # hackerspace-management environment variables # ----------------------------------------------------------------------------- # Copy to .env.local for development; set the same keys on your host for prod. # .env.local is git-ignored. Never commit real secrets. # ----------------------------------------------------------------------------- # Supabase (required) NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOi...replace-with-anon-key # Server-side admin key. Bypasses RLS. Required for createSpace / joinSpace. # Treat as a secret. Never expose to the browser. Never log it. SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOi...replace-with-service-role-key # App URL (required) # Public-facing base URL of this deployment. Used in OAuth redirects and in every # absolute link the app emits (dues emails, form-result links, the /me portal). # Set this to your own domain: it replaces the old hackerspace.sh fallback, so a # single-tenant instance never leaks the platform domain. No trailing slash. NEXT_PUBLIC_APP_URL=http://localhost:3000 # ----------------------------------------------------------------------------- # Single-tenant mode (optional). See docs/SINGLE_TENANT.md for the full guide. # ----------------------------------------------------------------------------- # Leave everything below unset to run the default MULTI-TENANT platform (one # deployment hosts many spaces, users create/join spaces at signup — the # hackerspace.sh model). Set NEXT_PUBLIC_SINGLE_TENANT=true to run a dedicated # instance for exactly ONE space: # - the "create a space" flow is disabled (server + UI), # - signup becomes "join THE space", # - the hackerspace.sh marketing/landing shell is hidden. # These are NEXT_PUBLIC_ because the signup page (a client component) reads them; # the server re-enforces every rule, so they are safe to expose. NEXT_PUBLIC_SINGLE_TENANT= # Brand name shown throughout the UI (logo wordmark, page titles). White-label # your instance here. Defaults to "hackerspace.sh" when unset. NEXT_PUBLIC_SITE_NAME= # The slug of your one space (matches spaces.slug, created by `pnpm setup`). # In single-tenant mode new signups join this space. If unset, the app falls # back to "the only space in the database". NEXT_PUBLIC_SINGLE_TENANT_SPACE_SLUG= # Set to "true" to let people sign up and join your space WITHOUT an invite code # (still subject to the space's require_approval setting — approve them from the # members page). Leave unset to require an invite code even in single-tenant mode. NEXT_PUBLIC_SINGLE_TENANT_OPEN_JOIN= # Override the marketing shell visibility. Defaults to ON for the platform and # OFF in single-tenant mode. Set "true" to keep the /resources subsite + landing # page, or "false" to hide them on a multi-tenant deploy. NEXT_PUBLIC_SHOW_MARKETING= # ----------------------------------------------------------------------------- # First-admin bootstrap (used ONLY by `pnpm setup`, never read at runtime). # `pnpm setup` provisions your one space and creates the first admin login from # these values (or from interactive prompts / CLI flags). Fill them in, run the # CLI once, then you can clear the password. See docs/SINGLE_TENANT.md. # ----------------------------------------------------------------------------- SETUP_SPACE_NAME= SETUP_SPACE_SLUG= SETUP_SPACE_CITY= SETUP_ADMIN_EMAIL= SETUP_ADMIN_PASSWORD= SETUP_ADMIN_NAME= # Secrets vault encryption key (required for the /ops Secrets feature). # 32 bytes of cryptographically random data, hex-encoded (64 hex chars). # Generate with: openssl rand -hex 32 # Without this set, the secrets feature falls back to legacy plain-text storage. # Rotating this key invalidates all existing ciphertexts; re-enter each secret. SECRETS_ENCRYPTION_KEY= # OAuth provider buttons on the login page (optional). # Set to "true" only for a provider you have actually configured in Supabase # Auth. Unset/anything-else hides that button (an unconfigured provider button # just dead-ends in a Supabase error). If neither is "true" the whole # "OR / social sign-in" block is hidden. NEXT_PUBLIC_OAUTH_GITHUB= NEXT_PUBLIC_OAUTH_GOOGLE= # Node env (optional, defaults to "development" locally) NODE_ENV=development # Transactional email (optional; required for dues-lifecycle notifications). # Resend HTTP API key (https://resend.com, starts with "re_"). Unset = the # notification outbox still fills but the dispatcher records each row as # failed with "transport not configured" instead of sending. RESEND_API_KEY= # From address for all platform email. Must be on a domain you have verified # in Resend (SPF + DKIM) for production delivery. Friendly name optional. # Example: HeatSync Labs EMAIL_FROM= # Shared secret guarding the notification dispatcher (/api/cron/notifications). # The droplet's crontab POSTs with "Authorization: Bearer $CRON_SECRET" once a # minute. Unset = the dispatcher returns 503 and never sends. Generate with: # openssl rand -hex 32 CRON_SECRET= # Error monitoring (optional). Sentry-format DSN for a self-hosted GlitchTip # (or any Sentry-compatible) ingest endpoint. Unset = the capture seam no-ops # (no events sent), so the app ships dark until the backend is provisioned. # Server-side capture only (money path, crons, server actions); no client SDK. # Example: https://@glitchtip.hackerspace.sh/1 SENTRY_DSN= # Docker build flag (only when building the standalone image) # Set to "1" in the Dockerfile so next.config.mjs emits standalone output. # DOCKER_BUILD=1 # ----------------------------------------------------------------------------- # Per-space integration credentials (PayPal, Zeffy, Venmo, Stripe) are stored # in the database under the `integrations` table, not in env. The # /api/paypal/sync endpoint reads them from there. # -----------------------------------------------------------------------------