Skip to main content
Sonamu uses .env files to apply different settings for each environment. Sensitive information such as database connection details, API keys, and session secrets should be stored in .env files and referenced from sonamu.config.ts.
Never commit .env files to Git! Make sure .env is included in your .gitignore.

Quick Start

Copy .env.example

Copy .env.example from the project root to create a .env file.
cp .env.example .env

Set Environment Variables

Open the .env file and modify it with actual values.
# Example
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your-db-password

Reference in Config File

Read environment variables using process.env in sonamu.config.ts.
database: {
  defaultOptions: {
    connection: {
      host: process.env.DB_HOST || "0.0.0.0",
      password: process.env.DB_PASSWORD,
    },
  },
}

.env File Structure

The .env file is written in KEY=VALUE format.
# Project Settings
PROJECT_NAME=MyProject

# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your-db-password

# Session
SESSION_SECRET=your-session-secret  # Minimum 64 characters
SESSION_SALT=your-session-salt  # Minimum 16 characters

# Storage (fs or s3)
DRIVE_DISK=fs

# AWS S3 (when DRIVE_DISK=s3)
AWS_ACCESS_KEY_ID=your-aws-access-key-id
AWS_SECRET_ACCESS_KEY=your-aws-secret-access-key
S3_REGION=ap-northeast-2
S3_BUCKET=my-bucket

# External APIs
OPENAI_API_KEY=your-openai-api-key

# Worker
DISABLE_WORKER=false
Comments start with #. Blank lines are ignored.

Environment-Specific Settings

.env.development
# Local development settings
PROJECT_NAME=MyProject-Dev

DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your-dev-password
DATABASE_NAME=myproject_dev

SESSION_SECRET=your-dev-session-secret
SESSION_SALT=your-dev-session-salt

DRIVE_DISK=fs

# Development OpenAI (optional)
OPENAI_API_KEY=sk-***

DISABLE_WORKER=false
Characteristics:
  • Uses local database
  • File system storage
  • Simple secret keys (security not required)

sonamu.config.ts Integration

How to use environment variables in sonamu.config.ts.

Basic Pattern

import { defineConfig } from "sonamu";

export default defineConfig({
  projectName: process.env.PROJECT_NAME ?? "DefaultName",
  
  database: {
    name: process.env.DATABASE_NAME ?? "database_name",
    defaultOptions: {
      connection: {
        host: process.env.DB_HOST || "0.0.0.0",
        port: Number(process.env.DB_PORT) || 5432,
        user: process.env.DB_USER || "postgres",
        password: process.env.DB_PASSWORD,
      },
    },
  },
  
  // ...
});

Nullish Coalescing vs OR

// Recommended: Only replaces undefined/null
const name = process.env.PROJECT_NAME ?? "DefaultName";

// undefined, null β†’ "DefaultName"
// ""(empty string) β†’ "" preserved
// 0 β†’ 0 preserved
Use ?? when you only want to use the default value if the environment variable is not set. || treats empty strings as falsy.

Number Conversion

// βœ… Correct method
port: Number(process.env.DB_PORT) || 5432

// ❌ Incorrect method
port: process.env.DB_PORT || 5432  // Can become string "5432"

Boolean Conversion

// βœ… Correct method
enableWorker: !["true", "1"].includes(process.env.DISABLE_WORKER ?? "false")

// Or
enableCache: process.env.ENABLE_CACHE === "true"

// ❌ Incorrect method
enableCache: process.env.ENABLE_CACHE || false  // "false" is also truthy

Security Best Practices

Generating Strong Secret Keys

# Generate 64-character random string
openssl rand -base64 48

# Or
node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"
SESSION_SECRET example:
SESSION_SECRET=your-64-character-random-session-secret-change-in-production
Minimum lengths:
  • SESSION_SECRET: 64+ characters
  • SESSION_SALT: 16+ characters
  • DB_PASSWORD: 32+ characters (production)

.gitignore Configuration

.gitignore
# Environment variables
.env
.env.local
.env.*.local

# Never commit production environment variables
.env.production

# Test environments may be allowed (if no sensitive info)
# .env.test

Maintaining .env.example

.env.example
# List keys only without actual values
PROJECT_NAME=

DB_HOST=localhost
DB_PORT=5432
DB_USER=
DB_PASSWORD=

SESSION_SECRET=
SESSION_SALT=
Commit .env.example to Git so team members can reference it.

File Permission Settings

# Set .env file permissions to owner read/write only
chmod 600 .env

# Verify
ls -la .env
# -rw------- 1 user user 512 Jan 09 10:00 .env

Restricting Environment Variable Access

// βœ… Access only where needed
const dbPassword = process.env.DB_PASSWORD;

// ❌ Never output to logs
console.log("Password:", process.env.DB_PASSWORD);

// ❌ Never expose to client
res.send({ secret: process.env.SESSION_SECRET });

GitHub Actions

.github/workflows/deploy.yml
jobs:
  deploy:
    steps:
      - name: Deploy
        env:
          DB_HOST: ${{ secrets.DB_HOST }}
          DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
          SESSION_SECRET: ${{ secrets.SESSION_SECRET }}
        run: |
          npm run deploy

Vercel/Netlify

  1. Project Settings β†’ Environment Variables
  2. Add each variable individually
  3. Set different values per environment (Production/Preview/Development)
Never use production secrets in development/staging environments!

Troubleshooting

Symptom: process.env.DB_PASSWORD is undefinedCauses:
  1. .env file doesn’t exist
  2. .env file is in wrong location
  3. Typo in variable name
  4. Server not restarted
Solution:
# 1. Check .env file
cat .env | grep DB_PASSWORD

# 2. Verify .env file location (project root)
ls -la .env

# 3. Restart server
npm run dev
Symptom: Changed environment variable but still using old valueCause:
  • Node.js only reads .env file when the process starts
  • Server restart required after file changes
Solution:
# Restart development server
# Stop with Ctrl+C then
npm run dev
HMR (Hot Module Replacement) only auto-reloads code; environment variables require a restart to apply.
Symptom: Works locally but undefined in productionCauses:
  • .env file doesn’t exist on production server
  • Hosting platform environment variables not configured
Solutions:Method 1: Deploy .env file to server
# After SSH connection
cd /path/to/app
nano .env
# Paste content and save
Method 2: Use hosting platform environment variables
  • Vercel: Project Settings β†’ Environment Variables
  • AWS EC2: /etc/environment or ~/.bashrc
  • Docker: docker run -e DB_HOST=... -e DB_PASSWORD=...

Next Steps