Getting Started
Environment Variables
Complete reference for all configuration options
Environment Variables
TL;DR: Copy
.env.exampleto.env.local, set the 3 required variables, done.
Quick Setup
cp .env.example .env.localMinimum required:
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/straktur"
BETTER_AUTH_SECRET="your-32-char-secret-here"
NEXT_PUBLIC_APP_URL="http://localhost:3000"Complete Reference
Core (Required)
| Variable | Type | Required | Description |
|---|---|---|---|
DATABASE_URL | string | Yes | PostgreSQL connection URL |
BETTER_AUTH_SECRET | string | Yes | Auth secret (min 32 chars) |
NEXT_PUBLIC_APP_URL | string | Yes | App URL for redirects |
NODE_ENV | enum | No | development | test | production |
Seed Data (Development)
| Variable | Type | Required | Default | Description |
|---|---|---|---|---|
ALLOW_DB_SEED | boolean | No | false | Enable db:seed command |
ALLOW_DB_RESET | boolean | No | false | Enable db:reset command |
SEED_USER_EMAIL | string | No | [email protected] | Demo user email |
SEED_USER_PASSWORD | string | No | password123 | Demo user password |
SEED_USER_NAME | string | No | Admin User | Demo user name |
SEED_ORG_NAME | string | No | Acme Inc | Demo organization name |
SEED_ORG_SLUG | string | No | acme | Demo organization slug |
| Variable | Type | Required | Default | Description |
|---|---|---|---|---|
EMAIL_PROVIDER | enum | No | console | console | smtp | resend |
EMAIL_FROM | string | No | noreply@localhost | Sender address |
EMAIL_REPLY_TO | string | No | - | Reply-to address |
SMTP options (when EMAIL_PROVIDER=smtp):
| Variable | Type | Required | Description |
|---|---|---|---|
SMTP_HOST | string | Yes | SMTP server host |
SMTP_PORT | string | Yes | SMTP port (587, 465, 25) |
SMTP_USER | string | Yes | SMTP username |
SMTP_PASS | string | Yes | SMTP password |
SMTP_SECURE | boolean | No | Use TLS (true for 465) |
Resend options (when EMAIL_PROVIDER=resend):
| Variable | Type | Required | Description |
|---|---|---|---|
RESEND_API_KEY | string | Yes | Resend API key |
File Storage
| Variable | Type | Required | Default | Description |
|---|---|---|---|---|
STORAGE_PROVIDER | enum | No | s3 | s3 | supabase |
STORAGE_INTENT_SECRET | string | No | - | Secret for signed upload URLs |
S3/R2/MinIO options (when STORAGE_PROVIDER=s3):
| Variable | Type | Required | Description |
|---|---|---|---|
S3_BUCKET | string | Yes | Bucket name |
S3_REGION | string | Yes | Region (e.g., us-east-1) |
S3_ENDPOINT | string | No | Custom endpoint (for R2/MinIO) |
S3_ACCESS_KEY_ID | string | Yes | Access key |
S3_SECRET_ACCESS_KEY | string | Yes | Secret key |
Supabase Storage options (when STORAGE_PROVIDER=supabase):
| Variable | Type | Required | Description |
|---|---|---|---|
SUPABASE_URL | string | Yes | Supabase project URL |
SUPABASE_SERVICE_KEY | string | Yes | Service role key |
SUPABASE_STORAGE_BUCKET | string | Yes | Storage bucket name |
Example Configurations
Development (minimal)
# .env.local
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/straktur"
BETTER_AUTH_SECRET="development-secret-min-32-characters-long"
NEXT_PUBLIC_APP_URL="http://localhost:3000"
# Enable seeding
ALLOW_DB_SEED="true"Development (with email preview)
# .env.local
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/straktur"
BETTER_AUTH_SECRET="development-secret-min-32-characters-long"
NEXT_PUBLIC_APP_URL="http://localhost:3000"
# Console email (prints to terminal)
EMAIL_PROVIDER="console"Production
# .env (production)
DATABASE_URL="postgresql://user:[email protected]:5432/straktur"
BETTER_AUTH_SECRET="<generated-secret>"
NEXT_PUBLIC_APP_URL="https://app.example.com"
NODE_ENV="production"
# Email via Resend
EMAIL_PROVIDER="resend"
EMAIL_FROM="[email protected]"
RESEND_API_KEY="re_xxx"
# Storage via S3
STORAGE_PROVIDER="s3"
S3_BUCKET="straktur-files"
S3_REGION="us-east-1"
S3_ACCESS_KEY_ID="AKIA..."
S3_SECRET_ACCESS_KEY="..."Adding New Variables
Environment variables are validated using T3 Env.
File: src/lib/env.ts
// src/lib/env.ts
import { createEnv } from "@t3-oss/env-nextjs"
import { z } from "zod"
export const env = createEnv({
server: {
// Add your server variable here
MY_NEW_VAR: z.string().min(1),
},
client: {
// Add your client variable here (must start with NEXT_PUBLIC_)
NEXT_PUBLIC_MY_VAR: z.string().optional(),
},
runtimeEnv: {
MY_NEW_VAR: process.env.MY_NEW_VAR,
NEXT_PUBLIC_MY_VAR: process.env.NEXT_PUBLIC_MY_VAR,
},
})Usage:
import { env } from "@/lib/env"
// Type-safe access
const value = env.MY_NEW_VARCommon Mistakes
❌ Wrong: Using process.env directly
const url = process.env.DATABASE_URL // No type safety!✅ Correct: Using env from lib
import { env } from "@/lib/env"
const url = env.DATABASE_URL // Type-safe + validatedRelated
- Installation - Initial setup
- Email Setup - Configure email providers
- Storage Setup - Configure file storage