Environment Configuration
Complete guide to all environment variables in Express Backend TS.
Configuration File
All configuration is done through the .env file in the root directory.
# Copy example configuration
cp .env.example .env
# Edit with your settings
nano .env
Environment Variables Reference
Application Settings
APP_NAME
APP_NAME=Base
- Type: String
- Default: Base
- Description: Application name shown in responses and emails
APP_MODE
APP_MODE=DEVELOPMENT
- Type: String
- Values:
DEVELOPMENT|PRODUCTION - Default:
DEVELOPMENT - Description: Application environment mode
- Impact:
PRODUCTION: Enables optimizations, disables verbose loggingDEVELOPMENT: Hot reload, detailed errors
APP_PORT
APP_PORT=3000
- Type: Number
- Default: 3000
- Description: Port on which the API server runs
- Production: Use
80for HTTP or443for HTTPS (requires sudo)
APP_URL
APP_URL=http://localhost:3000
- Type: URL
- Description: Full URL where your API is hosted
- Production: Use HTTPS (e.g.,
https://api.yourdomain.com)
APP_URL_FRONTEND
APP_URL_FRONTEND=http://localhost:4200
- Type: URL
- Description: Frontend application URL for CORS and email links
- Production: Your production frontend URL
APP_PREFIX_ROUTES
APP_PREFIX_ROUTES=/
- Type: String
- Default: /
- Description: Global prefix for all API routes
- Example: Set to
/apito have all routes start with/api
APP_VERSION
APP_VERSION=1.0.0
- Type: String
- Default: 1.0.0
- Description: Application version shown in API responses
Rate Limiting
RATE_LIMIT_WINDOW_MS
RATE_LIMIT_WINDOW_MS=60000
- Type: Number (milliseconds)
- Default:
60000(1 minute) - Description: Time window for rate limiting
RATE_LIMIT_MAX_REQUESTS
RATE_LIMIT_MAX_REQUESTS=100
- Type: Number
- Default:
100 - Description: Maximum requests per IP in window
- Recommended: 100-500 for public APIs
RATE_LIMIT_SKIP_IPS
RATE_LIMIT_SKIP_IPS="127.0.0.1"
- Type: String (comma-separated)
- Description: IP addresses to skip rate limiting
- Example:
"127.0.0.1,192.168.1.100"
API Security
X_API_KEY
X_API_KEY=key
- Type: String
- Required: Yes
- Description: API key for server-to-server authentication
- Security: Change this in production to a strong random value
Allowed Elements
ALLOWED_SUPPORTED_LANGUAGES
ALLOWED_SUPPORTED_LANGUAGES=fr,en
- Type: String (comma-separated)
- Default:
fr,en - Description: Supported languages for localization
ALLOWED_ORIGINS
ALLOWED_ORIGINS=http://localhost:4200,http://localhost:3000
- Type: String (comma-separated)
- Description: CORS allowed origins
- Production: Set to your production domains only
ALLOWED_METHODS
ALLOWED_METHODS=OPTIONS,HEAD,CONNECT,GET,POST,PUT,DELETE,PATCH
- Type: String (comma-separated)
- Description: Allowed HTTP methods for CORS
Feature Toggles
USE_DATABASE
USE_DATABASE=yes
- Type: Boolean String
- Values:
yes|no - Description: Enable MongoDB database
- Note: Required for most features
USE_RATELIMIT
USE_RATELIMIT=yes
- Type: Boolean String
- Values:
yes|no - Description: Enable rate limiting middleware
USE_MAIL
USE_MAIL=yes
- Type: Boolean String
- Values:
yes|no - Description: Enable email functionality
USE_QUEUE
USE_QUEUE=yes
- Type: Boolean String
- Values:
yes|no - Description: Enable Redis queue and Bull for background jobs
USE_CACHE
USE_CACHE=yes
- Type: Boolean String
- Values:
yes|no - Description: Enable Redis caching
SAVE_LOGS
SAVE_LOGS=yes
- Type: Boolean String
- Values:
yes|no - Description: Enable logging to database and files
Database Configuration
DATABASE_URL
DATABASE_URL="mongodb://[USER]:[PASSWORD]@localhost:27017/ExpressBaseTs?authSource=admin"
- Type: MongoDB Connection String
- Required: Yes (if
USE_DATABASE=yes) - Description: MongoDB connection URI
- Formats:
- Local:
mongodb://localhost:27017/database_name - With auth:
mongodb://username:password@localhost:27017/database_name?authSource=admin - MongoDB Atlas:
mongodb+srv://username:password@cluster.mongodb.net/database
- Local:
DATABASE_MAX_POOL_SIZE
DATABASE_MAX_POOL_SIZE=10
- Type: Number
- Default:
10 - Description: Maximum number of connections in the MongoDB connection pool
DATABASE_MIN_POOL_SIZE
DATABASE_MIN_POOL_SIZE=5
- Type: Number
- Default:
5 - Description: Minimum number of connections to maintain in the pool
DATABASE_SERVER_TIMEOUT
DATABASE_SERVER_TIMEOUT=5000
- Type: Number (milliseconds)
- Default:
5000 - Description: Server selection timeout
DATABASE_SOCKET_TIMEOUT
DATABASE_SOCKET_TIMEOUT=45000
- Type: Number (milliseconds)
- Default:
45000 - Description: Socket timeout for MongoDB connections
DATABASE_CONNECT_TIMEOUT
DATABASE_CONNECT_TIMEOUT=10000
- Type: Number (milliseconds)
- Default:
10000 - Description: Initial connection timeout
DATABASE_HEARTBEAT_FREQ
DATABASE_HEARTBEAT_FREQ=10000
- Type: Number (milliseconds)
- Default:
10000 - Description: Heartbeat frequency for monitoring server health
Redis Configuration
REDIS_QUEUE
REDIS_QUEUE=base
- Type: String
- Default:
base - Description: Base name for Redis queue instances
REDIS_HOST
REDIS_HOST=127.0.0.1
- Type: Hostname or IP
- Default:
127.0.0.1 - Description: Redis server hostname
REDIS_PORT
REDIS_PORT=6379
- Type: Number
- Default:
6379 - Description: Redis server port
REDIS_PASSWORD
REDIS_PASSWORD=password
- Type: String
- Description: Redis authentication password
- Production: Always set a strong password
Authentication & Security
SECRET_TOKEN
SECRET_TOKEN=e7950cdf52cb-9c334b569101e1bd2
- Type: String
- Required: Yes
- Description: Secret key for signing JWT access tokens
- Security:
- Minimum 32 characters
- Use cryptographically random string
- Generate:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" - CRITICAL: Change in production!
COOKIE_SECRET
COOKIE_SECRET=CRyXWsDHHCEkv
- Type: String
- Required: Yes
- Description: Secret for signing cookies
- Security: Must be different from SECRET_TOKEN
Email Configuration
The system supports two modes: Development (offline) and Production (online).
Template Path
TEMPLATE_PATH
TEMPLATE_PATH=templates
- Type: Path
- Default:
templates - Description: Directory containing Handlebars email templates
Development Email Settings (Offline)
Used when APP_MODE=DEVELOPMENT or for local testing with tools like MailDev.
MAIL_HOST_DEV
MAIL_HOST_DEV=localhost
- Type: Hostname
- Description: SMTP server for development (e.g., MailDev)
MAIL_PORT_DEV
MAIL_PORT_DEV=1025
- Type: Number
- Description: SMTP port for development
- Note: MailDev uses port 1025 by default
MAIL_SERVICE_DEV
MAIL_SERVICE_DEV=gmail
- Type: String
- Description: Email service name for development
MAIL_SENSER_NAME_DEV
MAIL_SENSER_NAME_DEV="Mr NJIFANDA"
- Type: String
- Description: Sender display name for development emails
MAIL_SENSER_EMAIL_DEV
MAIL_SENSER_EMAIL_DEV="contact@njifanda.com"
- Type: Email Address
- Description: Sender email address for development
MAIL_SECURE_DEV
MAIL_SECURE_DEV=false
- Type: Boolean
- Description: Use SSL/TLS for development emails
- Note: Set to
falsefor MailDev
MAIL_USER_DEV
MAIL_USER_DEV=false
- Type: String or Boolean
- Description: SMTP username for development (use
falseif not required)
MAIL_PASSWORD_DEV
MAIL_PASSWORD_DEV=false
- Type: String or Boolean
- Description: SMTP password for development (use
falseif not required)
Production Email Settings (Online)
Used when APP_MODE=PRODUCTION for real email delivery.
MAIL_HOST
MAIL_HOST=smtp.gmail.com
- Type: Hostname
- Description: SMTP server hostname
- Examples:
- Gmail:
smtp.gmail.com - SendGrid:
smtp.sendgrid.net - Mailgun:
smtp.mailgun.org
- Gmail:
MAIL_PORT
MAIL_PORT=587
- Type: Number
- Common Ports:
587: TLS (recommended)465: SSL25: Unencrypted (not recommended)
MAIL_SERVICE
MAIL_SERVICE=gmail
- Type: String
- Description: Email service name (gmail, sendgrid, etc.)
MAIL_SENSER_NAME
MAIL_SENSER_NAME="Mr NJIFANDA"
- Type: String
- Description: Sender display name for production emails
MAIL_SENSER_EMAIL
MAIL_SENSER_EMAIL="contact@njifanda.com"
- Type: Email Address
- Description: Sender email address for production
MAIL_SECURE
MAIL_SECURE=true
- Type: Boolean
- Values:
true|false - Description: Use SSL/TLS
- Recommended:
truefor port 465,falsefor port 587 (STARTTLS)
MAIL_USER
MAIL_USER=
- Type: String
- Description: SMTP authentication username
- Gmail: Use your full email address
MAIL_PASSWORD
MAIL_PASSWORD=
- Type: String
- Description: SMTP authentication password
- Gmail: Use App Password, not account password
- Security: Never commit this to version control
Admin User Configuration
Default admin user created by seeders.
USER_LASTNAME
USER_LASTNAME=Admin
- Type: String
- Description: Admin user's last name
USER_FIRSTNAME
USER_FIRSTNAME=Admin
- Type: String
- Description: Admin user's first name
USER_USERNAME
USER_USERNAME=admin
- Type: String
- Description: Admin user's username
USER_EMAIL
USER_EMAIL=admin@expressbase.com
- Type: Email Address
- Description: Admin user's email address
USER_PASSWORD
USER_PASSWORD=
- Type: String
- Description: Admin user's password
- Security: Set a strong password and never commit to version control
Logging Configuration
LOGGING_ENABLED
LOGGING_ENABLED=true
- Type: Boolean
- Default:
true - Description: Enable/disable logging system
LOGGING_TO_FILE
LOGGING_TO_FILE=true
- Type: Boolean
- Default:
true - Description: Write logs to files in LOGS_DIR
LOGGING_TO_DATABASE
LOGGING_TO_DATABASE=true
- Type: Boolean
- Default:
true - Description: Save logs to MongoDB database
MAX_LOG_QUEUE_SIZE
MAX_LOG_QUEUE_SIZE=1000
- Type: Number
- Default:
1000 - Description: Maximum number of logs in memory queue before forcing flush
LOG_BATCH_SIZE
LOG_BATCH_SIZE=10
- Type: Number
- Default:
10 - Description: Number of logs to write in each batch operation
LOG_PROCESS_INTERVAL
LOG_PROCESS_INTERVAL=5000
- Type: Number (milliseconds)
- Default:
5000 - Description: Interval between log batch processing
LOG_CLEANUP_DAYS
LOG_CLEANUP_DAYS=30
- Type: Number
- Default:
30 - Description: Days to keep old logs before automatic deletion
MAX_REQUEST_SIZE
MAX_REQUEST_SIZE=10mb
- Type: String
- Default:
10mb - Description: Maximum size for request body
- Examples:
1mb,5mb,10mb,50mb
LOGS_DIR
LOGS_DIR=.logs
- Type: Path
- Default:
.logs - Description: Directory for log files
Environment-Specific Configurations
Development (.env)
# Application
APP_NAME=Base
APP_MODE=DEVELOPMENT
APP_PORT=3000
APP_URL=http://localhost:3000
APP_URL_FRONTEND=http://localhost:4200
APP_PREFIX_ROUTES=/
APP_VERSION=1.0.0
# Rate Limit
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=1000
RATE_LIMIT_SKIP_IPS="127.0.0.1"
# API Key
X_API_KEY=dev-key
# Allowed Elements
ALLOWED_SUPPORTED_LANGUAGES=fr,en
ALLOWED_ORIGINS=http://localhost:4200,http://localhost:3000
ALLOWED_METHODS=OPTIONS,HEAD,CONNECT,GET,POST,PUT,DELETE,PATCH
# Use Services
USE_DATABASE=yes
USE_RATELIMIT=yes
USE_MAIL=yes
USE_QUEUE=yes
USE_CACHE=yes
SAVE_LOGS=yes
# Database (Local MongoDB)
DATABASE_URL="mongodb://localhost:27017/ExpressBaseTs"
DATABASE_MAX_POOL_SIZE=10
DATABASE_MIN_POOL_SIZE=5
# Redis (Local)
REDIS_QUEUE=base
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
# JWT (Development secrets - CHANGE IN PRODUCTION!)
SECRET_TOKEN=dev-secret-token-change-in-production
COOKIE_SECRET=dev-cookie-secret
# Email (MailDev for local testing)
TEMPLATE_PATH=templates
MAIL_HOST_DEV=localhost
MAIL_PORT_DEV=1025
MAIL_SERVICE_DEV=gmail
MAIL_SENSER_NAME_DEV="Development Team"
MAIL_SENSER_EMAIL_DEV="dev@localhost"
MAIL_SECURE_DEV=false
MAIL_USER_DEV=false
MAIL_PASSWORD_DEV=false
# Admin User
USER_LASTNAME=Admin
USER_FIRSTNAME=Admin
USER_USERNAME=admin
USER_EMAIL=admin@expressbase.com
USER_PASSWORD=admin123
# Logging
LOGGING_ENABLED=true
LOGGING_TO_FILE=true
LOGGING_TO_DATABASE=true
MAX_LOG_QUEUE_SIZE=1000
LOG_BATCH_SIZE=10
LOG_PROCESS_INTERVAL=5000
LOG_CLEANUP_DAYS=30
MAX_REQUEST_SIZE=10mb
LOGS_DIR=.logs
Production (.env.production)
# Application
APP_NAME=MyProductionApp
APP_MODE=PRODUCTION
APP_PORT=3000
APP_URL=https://api.yourdomain.com
APP_URL_FRONTEND=https://yourdomain.com
APP_PREFIX_ROUTES=/api
APP_VERSION=1.0.0
# Rate Limit (Stricter)
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=100
RATE_LIMIT_SKIP_IPS=""
# API Key (Strong random key)
X_API_KEY=prod-random-secure-api-key-here
# Allowed Elements
ALLOWED_SUPPORTED_LANGUAGES=fr,en
ALLOWED_ORIGINS=https://yourdomain.com
ALLOWED_METHODS=OPTIONS,HEAD,GET,POST,PUT,DELETE,PATCH
# Use Services
USE_DATABASE=yes
USE_RATELIMIT=yes
USE_MAIL=yes
USE_QUEUE=yes
USE_CACHE=yes
SAVE_LOGS=yes
# Database (MongoDB Atlas or production server)
DATABASE_URL="mongodb+srv://user:password@cluster.mongodb.net/production?retryWrites=true&w=majority"
DATABASE_MAX_POOL_SIZE=50
DATABASE_MIN_POOL_SIZE=10
DATABASE_SERVER_TIMEOUT=5000
DATABASE_SOCKET_TIMEOUT=45000
DATABASE_CONNECT_TIMEOUT=10000
DATABASE_HEARTBEAT_FREQ=10000
# Redis (Production instance)
REDIS_QUEUE=production
REDIS_HOST=your-redis-host.com
REDIS_PORT=6379
REDIS_PASSWORD=strong-redis-password
# JWT (Strong secrets generated with crypto)
SECRET_TOKEN=YOUR_GENERATED_STRONG_SECRET_HERE
COOKIE_SECRET=YOUR_GENERATED_COOKIE_SECRET_HERE
# Email (Production SMTP)
TEMPLATE_PATH=templates
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_SERVICE=gmail
MAIL_SENSER_NAME="Your Company"
MAIL_SENSER_EMAIL="noreply@yourdomain.com"
MAIL_SECURE=true
MAIL_USER=your-email@gmail.com
MAIL_PASSWORD=your-app-password
# Admin User
USER_LASTNAME=Admin
USER_FIRSTNAME=System
USER_USERNAME=admin
USER_EMAIL=admin@yourdomain.com
USER_PASSWORD=STRONG_PASSWORD_HERE
# Logging (Production settings)
LOGGING_ENABLED=true
LOGGING_TO_FILE=true
LOGGING_TO_DATABASE=true
MAX_LOG_QUEUE_SIZE=5000
LOG_BATCH_SIZE=50
LOG_PROCESS_INTERVAL=3000
LOG_CLEANUP_DAYS=90
MAX_REQUEST_SIZE=5mb
LOGS_DIR=/var/log/expressbase
Security Best Practices
Never Commit Secrets
Add to .gitignore:
.env
.env.local
.env.*.local
.env.production
Use Different Secrets Per Environment
- Development: Can use simple values for local testing
- Staging: Use production-like secrets
- Production: Use cryptographically secure secrets
Generate Secure Secrets
# Generate 32-byte hex string for SECRET_TOKEN
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Generate 64-byte base64 string
node -e "console.log(require('crypto').randomBytes(64).toString('base64'))"
Rotate Secrets Regularly
- Change JWT secrets every 3-6 months
- Invalidates all existing tokens
- Plan rotation during low-traffic periods
Validation
The application validates environment variables on startup. Missing required variables will prevent the application from starting.
Check your configuration:
npm run dev
Look for startup logs indicating which services are enabled.
Troubleshooting
Application Won't Start
Check for missing variables:
# View all env vars
printenv | grep -E "(DATABASE|REDIS|SECRET|MAIL)"
Validate .env syntax:
- No spaces around
= - Use quotes for values with spaces
- No trailing whitespace
Database Connection Fails
# Test MongoDB connection
mongosh "${DATABASE_URL}"
# Check URI encoding
# Special characters must be URL-encoded
Email Not Sending
# Test SMTP connection
telnet ${MAIL_HOST} ${MAIL_PORT}
# For Gmail
# - Enable 2FA
# - Generate App Password
# - Use App Password in MAIL_PASSWORD
Redis Connection Issues
# Test Redis connection
redis-cli -h ${REDIS_HOST} -p ${REDIS_PORT} -a ${REDIS_PASSWORD} ping
# Should respond: PONG
Next Steps
- Deployment Guide - Deploy to production
- Email System - Configure email templates
- Testing Guide - Test your application
Need help? Check the GitHub repository or contact support.