Environment Variables
All configuration is provided via environment variables. Set them in .env.local for local development, or as container environment variables for Docker/EC2 deployments.
Required
| Variable | Description |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | Your Supabase project URL (e.g., https://xyz.supabase.co). Used by the browser and as the fallback for server-side connections when SUPABASE_INTERNAL_URL is not set. Also used to derive the cookie name for session management. |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Supabase anon key (public, used in browser) |
SUPABASE_SERVICE_ROLE_KEY | Supabase service role key (secret, server-only) |
Optional — Networking
| Variable | Description |
|---|---|
SUPABASE_INTERNAL_URL | Server-only override for the Supabase URL. When set, all server-to-Supabase connections — including cookie-based SSR requests — use this URL instead of NEXT_PUBLIC_SUPABASE_URL. Cookie-based clients automatically have their cookie name overridden to match the one derived from NEXT_PUBLIC_SUPABASE_URL, so browser sessions continue to work correctly. The browser itself always uses NEXT_PUBLIC_SUPABASE_URL. Useful in Docker/Kubernetes environments where the server can reach Supabase over an internal network (e.g. http://supabase-kong:8000), avoiding egress through a public load balancer entirely. |
Optional — Application
| Variable | Default | Description |
|---|---|---|
DEFAULT_ADMIN_EMAIL | admin@example.com | Admin account email used by the setup script and on first startup. |
DEFAULT_ADMIN_PASSWORD | (none) | Admin account password applied on startup only if the password has never been changed. Must be set to a strong secret in production. |
MAX_BATCH_MUTATION | 100 | Maximum number of items that can be created, updated, or deleted in a single batch request. |
JSONB_SEARCH_MATCH_LIMIT | 150 | Maximum number of primary keys returned by the daas_search_item_ids RPC when ?search= targets a collection with json/jsonb columns. Keys are passed via the request URL (?id=in.(…)); very large lists can exceed proxy URL length limits (HTTP 414). Increase only if your reverse proxy allows longer URLs and your collections have json/jsonb columns with high result cardinality. |
Optional — Performance & Scaling
| Variable | Default | Description |
|---|---|---|
WEB_CONCURRENCY | (one worker per core) | Number of app worker processes (Docker only — the image starts cluster.js). Each worker is a full Next.js server (~400 MB resident under load). Set explicitly whenever the container memory limit is below cores × 400 MB, or the container OOM-loops on startup (e.g., a 1 GB limit → WEB_CONCURRENCY=2). See Docker. |
SUPABASE_JWT_SECRET | (unset) | Project JWT secret (Supabase Settings → API → JWT Settings). When set, HS256 access tokens are verified in-process instead of a GoTrue round trip per request. Only applies to users with an active daas_users row; everyone else falls back to GoTrue. Trade-off: a session revoked via logout stays valid until token expiry. |
PERMISSION_CACHE_TTL_MS | 30000 | TTL for cross-request permission caches (policy IDs, permission rows, admin/status flags, static tokens). Permission changes made through the API invalidate immediately; the TTL only bounds staleness for direct-SQL writes. 0 disables cross-request reuse. |
Optional — Runtime Env Whitelisting
These variables control which environment values are exposed to runtime automation code (extensions, cron jobs, custom services).
| Variable | Default | Description |
|---|---|---|
RUNTIME_ENV_WHITELIST_GLOBAL | (empty) | Comma-separated keys exposed to all runtime scopes |
RUNTIME_ENV_WHITELIST_EXTENSION | (empty) | Comma-separated keys exposed only to runtime extensions |
RUNTIME_ENV_WHITELIST_CRON | (empty) | Comma-separated keys exposed only to cron jobs |
RUNTIME_ENV_WHITELIST_CUSTOM_SERVICE | (empty) | Comma-separated keys exposed only to custom services |
Prefix-based exposure is also supported:
RUNTIME_PUBLIC_*(all scopes)EXTENSION_PUBLIC_*(extensions only)CRON_PUBLIC_*(cron only)CUSTOM_SERVICE_PUBLIC_*(custom services only)
For full examples and code usage, see Runtime Env Whitelisting.
Optional — CORS
These variables are the static fallback only. Once migrations have run, CORS is governed by the values in daas_settings (editable at Settings → CORS) and cached for 60 seconds; the env vars apply only when the settings row cannot be read. See CORS.
| Variable | Default | Description |
|---|---|---|
CORS_ENABLED | true | Whether CORS headers are set |
CORS_ORIGINS | (empty — blocks all) | Comma-separated allowed origins |
CORS_METHODS | GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS | Allowed HTTP methods |
CORS_ALLOWED_HEADERS | Content-Type, Authorization, Origin, X-Requested-With, Accept, X-Resource-Uri | Allowed request headers |
CORS_EXPOSE_HEADERS | (empty) | Headers exposed to the client |
CORS_ALLOW_CREDENTIALS | false | Set Access-Control-Allow-Credentials |
CORS_MAX_AGE | 600 | Preflight cache duration in seconds |
See CORS for examples.
Optional — SMTP (Email)
SMTP can be configured in Settings → SMTP (stored in daas_settings) or via environment variables. Settings values take precedence — on a migrated deployment the boolean and port fields always come from the database, so SMTP_ENABLED=true alone will not enable mail; enable it in Settings → SMTP. Env vars act as a fallback for fields left empty in Settings and when the settings row cannot be read.
| Variable | Default | Description |
|---|---|---|
SMTP_ENABLED | false | Enable SMTP email sending |
SMTP_HOST | (empty) | SMTP server hostname |
SMTP_PORT | 587 | SMTP port |
SMTP_USER | (empty) | SMTP username |
SMTP_PASSWORD | (empty) | SMTP password |
SMTP_FROM_EMAIL | (empty) | Sender email address (SMTP_FROM accepted as alias) |
SMTP_FROM_NAME | (empty) | Sender display name |
SMTP_SECURE | false | true for SSL/TLS, false for STARTTLS |
SMTP_IGNORE_TLS | false | Skip TLS entirely (not recommended in production) |
Security Notes
- Never commit
.env.localto version control SUPABASE_SERVICE_ROLE_KEYgrants full database access — keep it secretNEXT_PUBLIC_*variables are embedded in the browser bundle — never put secrets in themSUPABASE_INTERNAL_URLhas noNEXT_PUBLIC_prefix and is never sent to the browser