BunshipBunship
Operations

Environment and Configuration

Required environment variables for Bunship web + API runtime.

This page is the source of truth for required env vars in the current repo.

Code references:

  • web schema: apps/ship/src/env.ts
  • auth runtime: packages/auth/src/server.ts, packages/auth-clerk/src/server.ts
  • api runtime: apps/ship-api/src/server.ts and apps/ship-api/src/index.ts

Minimum Required (Web + API)

Without these variables, startup/build will fail or core auth/payment/storage flows will break.

VariableRequiredUsed byNotes
NEXT_PUBLIC_AUTH_PROVIDERYes (default better-auth)web, apibetter-auth or clerk
DATABASE_URLYesweb, api, authPostgres DSN
NEXT_PUBLIC_SITE_URLYesweb, api, authSite origin, supports comma-separated origins
NEXT_PUBLIC_SERVER_URLYesweb, api, authAPI origin
NEXT_PUBLIC_API_PREFIXNo (default /api/v1)web, api, authAPI route prefix
ADMIN_EMAIL_LISTYesweb, authComma-separated admin emails
EMAIL_FROMYesauthSender for verification/reset/OTP emails
RESEND_API_KEYYesweb/authEmail provider key
S3_ENDPOINTYesweb, apiStorage endpoint
S3_REGIONYesweb, apiStorage region
S3_ACCESS_KEYYesweb, apiStorage access key
S3_SECRET_KEYYesweb, apiStorage secret
S3_BUCKETYesweb, apiBucket name
NEXT_PUBLIC_S3_URL_BASEYesweb, apiPublic object URL base
STRIPE_SECRET_KEYYesweb, apiStripe API key
STRIPE_WEBHOOK_SECRETYesweb, apiStripe webhook signature secret
S_GITHUB_PERSONAL_ACCESS_TOKENYesweb, apiGitHub API access in admin/features
CLOUDFLARE_ACCOUNT_IDYes (in web schema)webRequired by current env validator

Better Auth only (when NEXT_PUBLIC_AUTH_PROVIDER=better-auth)

VariableRequiredUsed byNotes
BETTER_AUTH_SECRETYesauth/apiBetter Auth signing secret
BETTER_AUTH_URLYesauth/apiAuth base URL
AUTH_SECRETYesweb/authRequired by web env schema
OAUTH_GITHUB_CLIENT_IDYes (if GitHub OAuth enabled)web/authGitHub OAuth
OAUTH_GITHUB_CLIENT_SECRETYes (if GitHub OAuth enabled)web/authGitHub OAuth
OAUTH_GOOGLE_CLIENT_IDRecommendedauthGoogle OAuth server client ID
OAUTH_GOOGLE_CLIENT_SECRETRecommendedauthGoogle OAuth server secret
NEXT_PUBLIC_OAUTH_GOOGLE_CLIENT_IDYes (if Google OAuth enabled)webGoogle One Tap / Sign-In UI

Clerk only (when NEXT_PUBLIC_AUTH_PROVIDER=clerk)

VariableRequiredUsed byNotes
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEYYeswebClerk public key
CLERK_SECRET_KEYYesapi/authClerk server key
CLERK_WEBHOOK_SECRETYesapiUsed by /api/v1/webhook/clerk

API Runtime / Deployment Variables

VariableRequiredNotes
PORTNo (default 9001)API listen port
APP_ENVRecommendeddevelopment / production style env flag
NODE_ENVRecommendedNode runtime env
JWT_SECRETRecommendedAPI JWT signing secret (fallback exists but not safe for production)
JWT_EXPIRATIONNo (default 7d)API JWT TTL
GIT_COMMIT_SHANoBuild metadata for logs
BUILD_TIMENoBuild metadata for logs
CROSS_SUB_DOMAINOptionalCross-subdomain cookie domain

Optional Feature Variables

VariableFeature
UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKENKV/Redis features
NEXT_PUBLIC_GA_ID, NEXT_PUBLIC_UMAMI_DATA_IDAnalytics
NEXT_PUBLIC_APP_VERSION, VERCEL_GIT_COMMIT_SHAUI version display
BETTER_UPLOAD_PROVIDER, AWS_FORCE_PATH_STYLEUpload provider behavior
OPENAI_API_KEY, OPENAI_API_BASEAdmin AI command/copilot
REPLICATE_API_TOKENReplicate provider
KIE_API_KEY, KIE_API_BASE_URLKIE provider
FAL_API_KEYFAL provider

Local .env Example (Better Auth)

NEXT_PUBLIC_AUTH_PROVIDER=better-auth

DATABASE_URL=postgresql://postgres:postgres@localhost:5432/bunship
BETTER_AUTH_SECRET=replace-with-long-random-secret
BETTER_AUTH_URL=http://localhost:3001
AUTH_SECRET=replace-with-long-random-secret

NEXT_PUBLIC_SITE_URL=http://localhost:3000
NEXT_PUBLIC_SERVER_URL=http://localhost:3001
NEXT_PUBLIC_API_PREFIX=/api/v1

ADMIN_EMAIL_LIST=admin@example.com
EMAIL_FROM=Bunship <noreply@example.com>
RESEND_API_KEY=re_xxx

OAUTH_GITHUB_CLIENT_ID=xxx
OAUTH_GITHUB_CLIENT_SECRET=xxx
OAUTH_GOOGLE_CLIENT_ID=xxx
OAUTH_GOOGLE_CLIENT_SECRET=xxx
NEXT_PUBLIC_OAUTH_GOOGLE_CLIENT_ID=xxx

S3_ENDPOINT=https://s3.example.com
S3_REGION=auto
S3_ACCESS_KEY=xxx
S3_SECRET_KEY=xxx
S3_BUCKET=bunship
NEXT_PUBLIC_S3_URL_BASE=https://cdn.example.com

STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
S_GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxx
CLOUDFLARE_ACCOUNT_ID=xxx

Local .env Example (Clerk)

NEXT_PUBLIC_AUTH_PROVIDER=clerk

DATABASE_URL=postgresql://postgres:postgres@localhost:5432/bunship

NEXT_PUBLIC_SITE_URL=http://localhost:3000
NEXT_PUBLIC_SERVER_URL=http://localhost:3001
NEXT_PUBLIC_API_PREFIX=/api/v1

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxx
CLERK_SECRET_KEY=sk_test_xxx
CLERK_WEBHOOK_SECRET=whsec_xxx

ADMIN_EMAIL_LIST=admin@example.com
EMAIL_FROM=Bunship <noreply@example.com>
RESEND_API_KEY=re_xxx

S3_ENDPOINT=https://s3.example.com
S3_REGION=auto
S3_ACCESS_KEY=xxx
S3_SECRET_KEY=xxx
S3_BUCKET=bunship
NEXT_PUBLIC_S3_URL_BASE=https://cdn.example.com

STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
S_GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxx
CLOUDFLARE_ACCOUNT_ID=xxx