Skip to main content

Environment Variables

This guide explains all environment variables used in the boilerplate and how to configure them for different environments, including Temporal Cloud setup.

Configuration Files​

The boilerplate uses environment variables for configuration:

  • sample.env - Template with all available variables
  • .env - Your local configuration (not committed to git)
  • .env.production - Production overrides (optional)

Quick Start​

Copy the sample environment file:

cp sample.env .env

Edit .env with your configuration based on the sections below.

Complete Environment Variable Reference​

Node Server Configuration​

# Node environment: development | production | test
NODE_ENV=development

# Application name
APP_NAME='Node_API'

# Server port
PORT=3015

# Rate limiting (requests per minute)
THROTTLE_LIMIT=1500

# URL prefix
PREFIX=http://

# Domain
DOMAIN=api.test

# Timezone
TZ='Asia/Kolkata'

Details:

VariableRequiredDefaultDescription
NODE_ENVYesdevelopmentEnvironment mode (development, production, test)
APP_NAMEYesNode_APIApplication identifier for logs and monitoring
PORTYes3015HTTP server listening port
THROTTLE_LIMITNo1500Maximum requests per minute per IP
PREFIXNohttp://URL protocol prefix
DOMAINNoapi.testAPI domain name
TZNoUTCServer timezone (IANA format)

Common Timezones:

  • US East: America/New_York
  • US West: America/Los_Angeles
  • UK: Europe/London
  • India: Asia/Kolkata
  • Japan: Asia/Tokyo
  • UTC: UTC

PostgreSQL Database Configuration​

The boilerplate uses a PostgreSQL connection string:

# PostgreSQL connection string format
PG_DB="postgres://username:password@hostname:port/database"

Examples:

# Local development
PG_DB="postgres://postgres:postgres@localhost:5432/temporalapi"

# Production
PG_DB="postgres://dbuser:SecureP@ss@prod-db.example.com:5432/prod_db"

# With SSL
PG_DB="postgres://user:pass@host:5432/db?sslmode=require"

# With connection pooling params
PG_DB="postgres://user:pass@host:5432/db?pool_size=20&pool_timeout=30"

Connection String Format:

postgres://[user[:password]@][host][:port][/database][?options]

URL Encoding Special Characters:

If your password contains special characters, URL encode them:

CharacterEncoded
@%40
#%23
:%3A
/%2F
?%3F
&%26
=%3D

Example with special characters:

# Password: P@ss#123
PG_DB="postgres://user:P%40ss%23123@localhost:5432/mydb"

Database Setup:

# Create database
createdb temporalapi

# With specific user
createdb -U postgres temporalapi

# Test connection
psql "postgres://postgres:postgres@localhost:5432/temporalapi" -c "SELECT version();"

# Run migrations
npm run migrate

Common Connection Parameters:

# SSL enabled
PG_DB="postgres://user:pass@host:5432/db?sslmode=require"

# SSL with certificate verification disabled (not recommended for production)
PG_DB="postgres://user:pass@host:5432/db?sslmode=require&sslverify=false"

# Connection pool settings
PG_DB="postgres://user:pass@host:5432/db?pool_size=20&pool_timeout=30"

# Connection timeout
PG_DB="postgres://user:pass@host:5432/db?connect_timeout=10"

File Storage Configuration​

# File storage path
FS_PATH=/Users/darshit/nfs/api

Usage:

  • Directory for file uploads, temporary files, and logs
  • Must have read/write permissions
  • Use absolute paths

Setup:

# Create directory
mkdir -p /path/to/storage

# Set permissions
chmod 755 /path/to/storage

# Verify writable
touch /path/to/storage/test.txt && rm /path/to/storage/test.txt

Production recommendations:

  • Use dedicated storage volume or NFS mount
  • Regular backups
  • Monitor disk space
  • Set up log rotation

Email/SMTP Configuration​

# Mail server configuration
SMTP_HOST=localhost
SMTP_SECURE=false
SMTP_IGNORETLS=true
SMTP_PORT=1025
SMTP_USER=notifications@api.test
SMTP_AUTH_USER=api/api-dev
SMTP_AUTH_PASS='sfsff'

Details:

VariableDescription
SMTP_HOSTSMTP server hostname
SMTP_PORTSMTP server port (25, 587, or 465)
SMTP_SECUREUse TLS (true for port 465)
SMTP_IGNORETLSIgnore TLS certificate errors (dev only)
SMTP_USERSender email address
SMTP_AUTH_USERSMTP authentication username
SMTP_AUTH_PASSSMTP authentication password

Development Setup (MailHog)​

For local development, use MailHog to test emails:

# Start MailHog with Docker
docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog

# Configuration
SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_SECURE=false
SMTP_IGNORETLS=true
SMTP_USER=dev@localhost
SMTP_AUTH_USER=dev
SMTP_AUTH_PASS='dev'

View emails at: http://localhost:8025

Production SMTP Services​

Gmail:

SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_IGNORETLS=false
SMTP_USER=your-email@gmail.com
SMTP_AUTH_USER=your-email@gmail.com
SMTP_AUTH_PASS='your-app-password'

SendGrid:

SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_SECURE=false
SMTP_IGNORETLS=false
SMTP_USER=apikey
SMTP_AUTH_USER=apikey
SMTP_AUTH_PASS='your-sendgrid-api-key'

AWS SES:

SMTP_HOST=email-smtp.us-east-1.amazonaws.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_IGNORETLS=false
SMTP_USER=your-ses-smtp-username
SMTP_AUTH_USER=your-ses-smtp-username
SMTP_AUTH_PASS='your-ses-smtp-password'

Mailgun:

SMTP_HOST=smtp.mailgun.org
SMTP_PORT=587
SMTP_SECURE=false
SMTP_IGNORETLS=false
SMTP_USER=postmaster@your-domain.mailgun.org
SMTP_AUTH_USER=postmaster@your-domain.mailgun.org
SMTP_AUTH_PASS='your-mailgun-password'

Temporal Configuration​

Local Temporal Server​

For local development with Temporal running on your machine:

# Temporal server address
TEMPORAL_ADDRESS=localhost:7233

# Namespace
TEMPORAL_NAMESPACE=default

# Task queue name
TEMPORAL_TASK_QUEUE=loan-underwriter-queue

# Maximum concurrent workers
MAX_WORKERS=10

Starting Local Temporal:

# Option 1: Docker
docker run -d -p 7233:7233 -p 8233:8233 temporalio/auto-setup:latest

# Option 2: Temporal CLI
temporal server start-dev

# Option 3: Homebrew (macOS)
brew install temporal
temporal server start-dev

Access Temporal UI: http://localhost:8233

Temporal Cloud Configuration​

For production deployment with Temporal Cloud:

# Temporal Cloud endpoint
TEMPORAL_ADDRESS=your-namespace.account-id.tmprl.cloud:7233

# Your Temporal Cloud namespace
TEMPORAL_NAMESPACE=your-namespace.account-id

# Task queue name
TEMPORAL_TASK_QUEUE=production-queue

# Maximum concurrent workers
MAX_WORKERS=20

# Optional: API Key for authentication
TEMPORAL_API_KEY=your-api-key-here

# Optional: TLS certificate paths
TEMPORAL_CLIENT_CERT_PATH=/path/to/client.pem
TEMPORAL_CLIENT_KEY_PATH=/path/to/client-key.pem

Setting Up Temporal Cloud​

Step 1: Get Temporal Cloud Credentials​

  1. Sign up at Temporal Cloud
  2. Create a namespace (e.g., myapp)
  3. Note your namespace format: myapp.a2c3z (namespace + account ID)
  4. Download certificates:
    • Client certificate (client.pem)
    • Client private key (client-key.pem)

Step 2: Configure Environment​

Option A: Using Certificate Files (Recommended)

# .env
TEMPORAL_ADDRESS=myapp.a2c3z.tmprl.cloud:7233
TEMPORAL_NAMESPACE=myapp.a2c3z
TEMPORAL_TASK_QUEUE=production-queue
MAX_WORKERS=20

# Store certificates in a secure location
TEMPORAL_CLIENT_CERT_PATH=/app/certs/client.pem
TEMPORAL_CLIENT_KEY_PATH=/app/certs/client-key.pem

Option B: Using API Key (if supported)

TEMPORAL_ADDRESS=myapp.a2c3z.tmprl.cloud:7233
TEMPORAL_NAMESPACE=myapp.a2c3z
TEMPORAL_TASK_QUEUE=production-queue
MAX_WORKERS=20
TEMPORAL_API_KEY=your-temporal-cloud-api-key

Step 3: Secure Certificate Storage​

Docker Secrets:

# docker-compose.yml
version: '3.8'
services:
api:
image: your-api:latest
secrets:
- temporal_client_cert
- temporal_client_key
environment:
TEMPORAL_CLIENT_CERT_PATH: /run/secrets/temporal_client_cert
TEMPORAL_CLIENT_KEY_PATH: /run/secrets/temporal_client_key

secrets:
temporal_client_cert:
file: ./certs/client.pem
temporal_client_key:
file: ./certs/client-key.pem

Kubernetes Secrets:

# Create secret from files
kubectl create secret generic temporal-certs \
--from-file=client.pem=./certs/client.pem \
--from-file=client-key.pem=./certs/client-key.pem

# Reference in deployment
apiVersion: v1
kind: Pod
spec:
containers:
- name: api
env:
- name: TEMPORAL_CLIENT_CERT_PATH
value: /app/certs/client.pem
- name: TEMPORAL_CLIENT_KEY_PATH
value: /app/certs/client-key.pem
volumeMounts:
- name: temporal-certs
mountPath: /app/certs
readOnly: true
volumes:
- name: temporal-certs
secret:
secretName: temporal-certs

Temporal Configuration Details​

VariableRequiredDefaultDescription
TEMPORAL_ADDRESSYeslocalhost:7233Temporal server address
TEMPORAL_NAMESPACEYesdefaultTemporal namespace
TEMPORAL_TASK_QUEUEYes-Task queue name for workers
MAX_WORKERSNo10Maximum concurrent workflow/activity executions
TEMPORAL_API_KEYNo-API key for cloud authentication
TEMPORAL_CLIENT_CERT_PATHNo*-Path to client certificate
TEMPORAL_CLIENT_KEY_PATHNo*-Path to client private key

* Required for Temporal Cloud with certificate-based auth

Environment-Specific Configurations​

Development (.env)​

NODE_ENV=development
APP_NAME='Node_API_Dev'
PORT=3015
THROTTLE_LIMIT=9999
TZ='Asia/Kolkata'

FS_PATH=/Users/darshit/dev/storage

SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_SECURE=false
SMTP_IGNORETLS=true

PG_DB="postgres://postgres:postgres@localhost:5432/temporalapi_dev"

TEMPORAL_ADDRESS=localhost:7233
TEMPORAL_NAMESPACE=default
TEMPORAL_TASK_QUEUE=dev-queue
MAX_WORKERS=5

Staging (.env.staging)​

NODE_ENV=production
APP_NAME='Node_API_Staging'
PORT=3015
THROTTLE_LIMIT=1500
TZ='UTC'

FS_PATH=/var/app/storage

SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_SECURE=false
SMTP_AUTH_USER=apikey
SMTP_AUTH_PASS=${SENDGRID_API_KEY}

PG_DB="postgres://staginguser:${DB_PASSWORD}@staging-db.internal:5432/temporalapi_staging?sslmode=require"

TEMPORAL_ADDRESS=staging-namespace.a2c3z.tmprl.cloud:7233
TEMPORAL_NAMESPACE=staging-namespace.a2c3z
TEMPORAL_TASK_QUEUE=staging-queue
MAX_WORKERS=10
TEMPORAL_CLIENT_CERT_PATH=/app/certs/staging-client.pem
TEMPORAL_CLIENT_KEY_PATH=/app/certs/staging-client-key.pem

Production (.env.production)​

NODE_ENV=production
APP_NAME='Node_API'
PORT=3015
THROTTLE_LIMIT=1500
TZ='UTC'

FS_PATH=/var/app/storage

SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_SECURE=false
SMTP_AUTH_USER=apikey
SMTP_AUTH_PASS=${SENDGRID_API_KEY}

PG_DB="postgres://produser:${DB_PASSWORD}@prod-db.internal:5432/temporalapi?sslmode=require"

TEMPORAL_ADDRESS=prod-namespace.a2c3z.tmprl.cloud:7233
TEMPORAL_NAMESPACE=prod-namespace.a2c3z
TEMPORAL_TASK_QUEUE=production-queue
MAX_WORKERS=20
TEMPORAL_CLIENT_CERT_PATH=/app/certs/client.pem
TEMPORAL_CLIENT_KEY_PATH=/app/certs/client-key.pem

Security Best Practices​

DO NOT Commit Secrets​

Add to .gitignore:

.env
.env.local
.env.*.local
.env.production
.env.staging
*.pem
*.key
*.crt
certs/

Use Secrets Management​

AWS Secrets Manager:

# Store secret
aws secretsmanager create-secret \
--name /myapp/db/password \
--secret-string "super-secret-password"

# Retrieve in app (use AWS SDK)
const password = await getSecret('/myapp/db/password');

HashiCorp Vault:

# Store secret
vault kv put secret/myapp/db password="super-secret"

# Retrieve
vault kv get -field=password secret/myapp/db

Environment Variables from Secrets:

# Load from secrets manager in startup script
export PG_DB=$(aws secretsmanager get-secret-value --secret-id db-connection --query SecretString --output text)
export TEMPORAL_API_KEY=$(vault kv get -field=api-key secret/temporal)

# Start app
npm start

Generate Secure Passwords​

# Generate random password
openssl rand -base64 32

# Generate API key
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Troubleshooting​

Database Connection Issues​

Problem: ECONNREFUSED or connection timeout

Solutions:

  1. Verify PostgreSQL is running:
pg_isready -h localhost -p 5432
  1. Test connection string:
psql "postgres://postgres:postgres@localhost:5432/temporalapi" -c "SELECT 1;"
  1. Check credentials:
# List databases
psql -U postgres -l

# Connect to database
psql -U postgres -d temporalapi
  1. Check special characters in password:
# URL encode the password
# Example: P@ss#123 becomes P%40ss%23123
PG_DB="postgres://user:P%40ss%23123@localhost:5432/db"

Temporal Cloud Connection Issues​

Problem: Error: connect ECONNREFUSED or timeout

Solutions:

  1. Verify address format:
# Correct format
TEMPORAL_ADDRESS=namespace.account-id.tmprl.cloud:7233
  1. Check certificates:
# Verify certificate files exist and are readable
ls -la /path/to/certs/
cat /path/to/certs/client.pem
  1. Test connectivity:
# Check if port 7233 is accessible
telnet namespace.account-id.tmprl.cloud 7233
  1. Verify firewall allows outbound connections on port 7233

Email Not Sending​

Problem: Emails not being sent or received

Solutions:

  1. Check SMTP credentials:
# Test SMTP connection
telnet smtp.gmail.com 587
  1. For Gmail, use App Password (not account password):

    • Go to Google Account → Security → 2-Step Verification → App passwords
    • Generate app password
    • Use that as SMTP_AUTH_PASS
  2. Check SMTP logs in your application

  3. Use MailHog for local testing:

docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog

Environment Variables Not Loading​

Problem: Variables showing as undefined

Solutions:

  1. Verify .env file location (must be in project root)
  2. Check file name is exactly .env (not .env.txt)
  3. Ensure dotenv is loaded:
require('dotenv').config(); // CommonJS
// or
import 'dotenv/config'; // ES Modules
  1. Check for syntax errors in .env:
# No spaces around =
CORRECT=value
WRONG = value

# Quotes for values with spaces
APP_NAME='My App'

Complete Example Configuration​

Here's a complete .env.example for reference:

# ===================================================================
# NODE SERVER CONFIGURATION
# ===================================================================
NODE_ENV=development
APP_NAME='Node_API'
PORT=3015
THROTTLE_LIMIT=1500
PREFIX=http://
DOMAIN=api.test
TZ='Asia/Kolkata'

# ===================================================================
# FILE STORAGE
# ===================================================================
FS_PATH=/Users/darshit/nfs/api

# ===================================================================
# EMAIL/SMTP CONFIGURATION
# ===================================================================
SMTP_HOST=localhost
SMTP_SECURE=false
SMTP_IGNORETLS=true
SMTP_PORT=1025
SMTP_USER=notifications@api.test
SMTP_AUTH_USER=api/api-dev
SMTP_AUTH_PASS='sfsff'

# ===================================================================
# POSTGRESQL DATABASE
# ===================================================================
PG_DB="postgres://postgres:postgres@localhost:5432/temporalapi"

# ===================================================================
# TEMPORAL WORKFLOW ORCHESTRATION
# ===================================================================
# For local: localhost:7233, default
# For cloud: your-namespace.account-id.tmprl.cloud:7233, your-namespace.account-id
TEMPORAL_ADDRESS=localhost:7233
TEMPORAL_NAMESPACE=default
TEMPORAL_TASK_QUEUE=loan-underwriter-queue
MAX_WORKERS=10

# Optional for Temporal Cloud
# TEMPORAL_API_KEY=your-api-key-here
# TEMPORAL_CLIENT_CERT_PATH=/path/to/client.pem
# TEMPORAL_CLIENT_KEY_PATH=/path/to/client-key.pem

Next Steps​