A live checklist of the integrations this instance needs. Values are never shown here, only whether each one is present.
This instance is not production ready
Connected. Data mode is supabase.
Supabase provides Postgres with row level security, authentication (email, OAuth providers) and private storage for locked media. Without it the app runs on the development store, which is fine locally and must not be used in production.
| Variable | Required | Note |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | Yes | Project URL from the Supabase dashboard. |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Yes | Public anon key. Safe for the browser; RLS enforces access. |
SUPABASE_SERVICE_ROLE_KEY | Yes | Server only. Used for privileged operations such as ledger writes and approvals. |
FANRIG_DATA_MODE | Optional | Force development or supabase. Leave unset to auto detect. |
Not configured. Purchases and membership checkout show a setup required state.
Stripe Checkout and saved cards handle purchases (post unlocks, tips, paid messages, live tickets, custom requests) and Checkout handles memberships (subscriptions), Stripe Connect Express pays creators and the Billing Portal lets fans manage invoices. A purchase is granted and a membership activated only from a confirmed Stripe result (the PaymentIntent status or the webhook), so the webhook secret is mandatory.
| Variable | Required | Note |
|---|---|---|
STRIPE_SECRET_KEY | Yes | Server only secret key. |
STRIPE_WEBHOOK_SECRET | Yes | Signing secret for the /api/stripe/webhook endpoint. |
STRIPE_CONNECT_WEBHOOK_SECRET | Optional | Signing secret of the Connect endpoint (account.updated) on the same route. |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Optional | Needed only for embedded payment elements. |
Set.
Signs the development session cookie and other short lived tokens. Generate at least 32 random bytes and keep it out of version control.
| Variable | Required | Note |
|---|---|---|
FANRIG_SESSION_SECRET | Yes | Random string, 32 bytes or more. |
MFA_ENCRYPTION_KEY | Optional | Recommended. Encrypts authenticator secrets; falls back to FANRIG_SESSION_SECRET. Keep it when the session secret rotates. |
NEXT_PUBLIC_APP_URL | Yes | Canonical public URL, used for redirects, emails, the sitemap and image watermarks. |
Supabase Storage, private bucket "media". ffmpeg 8.0.1-3ubuntu2 found, videos are processed.
Uploads are stored privately and only served after an access check on every request. Images are processed by the bundled sharp library (orientation, metadata removal, sizes, blurred previews). Videos need the ffmpeg and ffprobe programs on the server: apt install ffmpeg on Debian or Ubuntu, apk add ffmpeg on Alpine, brew install ffmpeg on macOS. Restart is not needed after installing; retry failed videos from the vault.
| Variable | Required | Note |
|---|---|---|
MEDIA_STORAGE | Optional | local or supabase. Defaults to supabase in Supabase data mode, local otherwise. |
MEDIA_ROOT | Optional | Folder for local storage (default .fanrig-dev/media). Use a persistent disk and back it up. |
MEDIA_SUPABASE_BUCKET | Optional | Private Supabase Storage bucket (default media, created by the migrations). |
FFMPEG_PATH | Optional | Path to ffmpeg when it is not on PATH. ffprobe is looked up next to it. |
FFPROBE_PATH | Optional | Path to ffprobe when it is elsewhere. |
MEDIA_URL_SECRET | Optional | Secret for opaque media URLs. Defaults to FANRIG_SESSION_SECRET. |
Configured. Email goes out through your SMTP server.
Any SMTP provider works: Namecheap Private Email, Gmail with an app password, Amazon SES or Resend. Every attempt is logged in Admin, Email, where you can also send a test email. Configure the same server in Supabase Auth so sign up and password emails use it too.
| Variable | Required | Note |
|---|---|---|
SMTP_HOST | Yes | For example mail.privateemail.com, smtp.gmail.com, email-smtp.<region>.amazonaws.com or smtp.resend.com. |
SMTP_PORT | Optional | 465 for TLS, 587 for STARTTLS. Defaults from SMTP_SECURE. |
SMTP_SECURE | Optional | true for port 465. Defaults to true on 465. |
SMTP_USER | Yes | Login of the mailbox or provider (Resend: resend). |
SMTP_PASS | Yes | Password, app password or API key. Server only. |
EMAIL_FROM | Optional | Sender, for example Fanrig <no-reply@yourdomain.com>. |
Configured. People can turn on push in their notification settings.
Push uses VAPID keys and the browsers' push services (Chrome, Edge, Firefox, Safari). Generate the keys once with npm run vapid:generate and keep them: new keys invalidate every existing subscription. The webPush feature flag in admin settings must be on. On iPhone and iPad push works after the app is added to the home screen.
| Variable | Required | Note |
|---|---|---|
VAPID_PUBLIC_KEY | Yes | Public key from npm run vapid:generate. |
VAPID_PRIVATE_KEY | Yes | Private key. Server only. |
VAPID_SUBJECT | Yes | Contact for push services: mailto:ops@yourdomain.com or an https URL. |
WEB_PUSH_ALLOWED_HOSTS | Optional | Extra push service hosts to accept, comma separated. |
In process delivery. Correct for a single server process; set REALTIME_DATABASE_URL when you run several instances.
Badges, toasts, message threads and admin progress update live over server sent events on /api/realtime. Behind nginx, turn off buffering for that path (the deploy kit does).
| Variable | Required | Note |
|---|---|---|
REALTIME_DATABASE_URL | Optional | Direct Postgres connection (not a transaction pooler). Needed for PM2 cluster mode, several servers or serverless hosting. |
REALTIME_MAX_CONNECTIONS_PER_USER | Optional | Open tabs per account receiving live updates. Default 5. |
Not configured. The live studio shows a setup required state and viewers see that live streaming is not available.
Live video runs on LiveKit: LiveKit Cloud (create a project and copy its URL, API key and secret) or your own LiveKit server with TLS on its domain and TURN enabled. The app signs short lived tokens on the server: viewers receive a subscribe only token after the entitlement check, the creator a publisher token, and rooms are created and closed through the LiveKit server API. Stories need no extra service.
| Variable | Required | Note |
|---|---|---|
LIVEKIT_URL | Yes | WebSocket URL, for example wss://yourproject.livekit.cloud or wss://live.example.com. |
LIVEKIT_API_KEY | Yes | API key of the LiveKit project or server. |
LIVEKIT_API_SECRET | Yes | Its secret. Server only, never sent to browsers. |
Set. Call /api/cron/all every few minutes from a crontab or Vercel Cron.
The scheduler calls /api/cron/all with the secret as a bearer token; it runs every job whose interval has elapsed (publishing scheduled posts, resuming announcements, log cleanup). Runs are logged with their duration and outcome in Admin, Email.
| Variable | Required | Note |
|---|---|---|
CRON_SECRET | Yes | Random string. Sent as Authorization: Bearer <secret>. |
After changing environment variables, restart the server. In development mode you can sign in with the seeded accounts listed on the login page.