Alepha loads environment variables from .env files in development. In production, use your platform's environment configuration.
Every production deployment needs:
| Variable | Description |
|---|---|
NODE_ENV |
Set to production |
APP_SECRET |
Long random string for signing cookies and tokens |
DATABASE_URL |
Your database connection string |
# Generate a secure random string
openssl rand -base64 32
Use a different secret for each environment (development, staging, production).
# Standard format
DATABASE_URL=postgres://user:pass@host:5432/database
# With SSL (required for most cloud providers)
DATABASE_URL=postgres://user:pass@host:5432/database?sslmode=require
DATABASE_URL=cloudflare-d1://binding-name:database-id
DATABASE_URL=sqlite://./data.db
VERCEL_PROJECT_ID=prj_...
VERCEL_ORG_ID=team_...
BLOB_READ_WRITE_TOKEN=vercel_blob_...
CLOUDFLARE_API_TOKEN=...
CLOUDFLARE_ACCOUNT_ID=...
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=us-east-1
S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...
S3_REGION=us-east-1
S3_ENDPOINT=https://... # Optional, for non-AWS S3
S3_FORCE_PATH_STYLE=true # Optional, for MinIO
BLOB_READ_WRITE_TOKEN=vercel_blob_...
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASS=SG...
SMTP_FROM=noreply@example.com
TWILIO_ACCOUNT_SID=AC...
TWILIO_AUTH_TOKEN=...
TWILIO_FROM=+1234567890
REDIS_URL=redis://localhost:6379
# or with authentication
REDIS_URL=redis://:password@host:6379
Alepha supports multiple .env files:
.env # Default, loaded in all environments
.env.local # Local overrides (gitignored)
.env.development # Development-specific
.env.production # Production-specific
.env.test # Test-specific
Load order (later files override earlier):
.env.env.local.env.[mode].env.[mode].localDefine and validate environment variables with $env:
1import { $env } from "alepha"; 2 3class Config { 4 env = $env({ 5 DATABASE_URL: t.string(), 6 APP_SECRET: t.string({ minLength: 32 }), 7 SMTP_HOST: t.optional(t.string()), 8 MAX_UPLOAD_SIZE: t.optional(t.integer({ default: 10 })), 9 });10}
Access validated values:
1const config = inject(Config);2const dbUrl = config.env.DATABASE_URL; // string (validated)3const maxSize = config.env.MAX_UPLOAD_SIZE; // number (with default)
.env.local for local secrets, add to .gitignoreAPP_SECRET$env to fail fast on missing variables