Environment-Specific Configuration
PMDaemon supports environment-specific configurations to manage different deployment stages (development, staging, production) with tailored settings for each environment.
Environment Configuration Strategies
1. Multiple Config Files
Create separate ecosystem files for each environment:
ecosystem.dev.json # Development
ecosystem.staging.json # Staging
ecosystem.prod.json # Production
Development (ecosystem.dev.json):
{
"apps": [
{
"name": "web-app-dev",
"script": "npm",
"args": ["run", "dev"],
"cwd": "/app",
"env": {
"NODE_ENV": "development",
"PORT": "3000",
"DEBUG": "*",
"DB_URL": "mongodb://localhost:27017/myapp_dev"
},
"instances": 1,
"watch": true,
"ignore_watch": ["node_modules", "logs"],
"max_restarts": 10,
"min_uptime": "1s"
}
]
}
Production (ecosystem.prod.json):
{
"apps": [
{
"name": "web-app-prod",
"script": "dist/server.js",
"cwd": "/app",
"env": {
"NODE_ENV": "production",
"PORT": "3000"
},
"instances": "max",
"exec_mode": "cluster",
"watch": false,
"max_restarts": 3,
"min_uptime": "10s",
"max_memory_restart": "1G",
"health_check": {
"enabled": true,
"url": "http://localhost:3000/health",
"interval": 30,
"timeout": 10,
"retries": 3
}
}
]
}
2. Environment Variables Override
Use a single config file with environment variable substitution:
{
"apps": [
{
"name": "web-app",
"script": "${APP_SCRIPT:-server.js}",
"instances": "${APP_INSTANCES:-1}",
"env": {
"NODE_ENV": "${NODE_ENV:-development}",
"PORT": "${PORT:-3000}",
"DB_URL": "${DATABASE_URL}",
"REDIS_URL": "${REDIS_URL}"
},
"watch": "${WATCH_FILES:-false}",
"max_memory_restart": "${MAX_MEMORY:-500M}"
}
]
}
Development (.env.dev):
NODE_ENV=development
APP_SCRIPT=npm run dev
APP_INSTANCES=1
PORT=3000
WATCH_FILES=true
MAX_MEMORY=1G
DATABASE_URL=mongodb://localhost:27017/myapp_dev
REDIS_URL=redis://localhost:6379
Production (.env.prod):
NODE_ENV=production
APP_SCRIPT=dist/server.js
APP_INSTANCES=max
PORT=3000
WATCH_FILES=false
MAX_MEMORY=2G
DATABASE_URL=mongodb://prod-cluster:27017/myapp
REDIS_URL=redis://prod-redis:6379
3. Conditional Configuration
Use environment-based conditional logic:
{
"apps": [
{
"name": "web-app",
"script": "server.js",
"env": {
"NODE_ENV": "development"
},
"env_development": {
"NODE_ENV": "development",
"PORT": "3000",
"DEBUG": "*",
"DB_URL": "mongodb://localhost:27017/myapp_dev"
},
"env_staging": {
"NODE_ENV": "staging",
"PORT": "3000",
"DB_URL": "mongodb://staging-db:27017/myapp_staging"
},
"env_production": {
"NODE_ENV": "production",
"PORT": "3000",
"DB_URL": "mongodb://prod-cluster:27017/myapp"
}
}
]
}
Environment-Specific Settings
Development Environment
Characteristics:
- Fast iteration and debugging
- File watching enabled
- Detailed logging
- Relaxed restart policies
Configuration:
{
"apps": [
{
"name": "dev-app",
"script": "npm run dev",
"watch": true,
"ignore_watch": ["node_modules", "*.log"],
"env": {
"NODE_ENV": "development",
"DEBUG": "*",
"LOG_LEVEL": "debug"
},
"instances": 1,
"max_restarts": 50,
"min_uptime": "1s",
"restart_delay": 100
}
]
}
Staging Environment
Characteristics:
- Production-like setup
- Testing and validation
- Moderate monitoring
- Controlled resource usage
Configuration:
{
"apps": [
{
"name": "staging-app",
"script": "dist/server.js",
"instances": 2,
"exec_mode": "cluster",
"env": {
"NODE_ENV": "staging",
"LOG_LEVEL": "info"
},
"max_restarts": 5,
"min_uptime": "5s",
"max_memory_restart": "800M",
"health_check": {
"enabled": true,
"url": "http://localhost:3000/health",
"interval": 60
}
}
]
}
Production Environment
Characteristics:
- Maximum performance and reliability
- Comprehensive monitoring
- Strict resource limits
- Minimal restarts
Configuration:
{
"apps": [
{
"name": "prod-app",
"script": "dist/server.js",
"instances": "max",
"exec_mode": "cluster",
"env": {
"NODE_ENV": "production",
"LOG_LEVEL": "warn"
},
"max_restarts": 3,
"min_uptime": "10s",
"max_memory_restart": "1G",
"kill_timeout": 5000,
"health_check": {
"enabled": true,
"url": "http://localhost:3000/health",
"interval": 30,
"timeout": 5,
"retries": 3
},
"monitoring": {
"cpu_threshold": 80,
"memory_threshold": 85
}
}
]
}
Deployment Strategies
1. Environment-Specific Deployment
# Development
pmdaemon start ecosystem.dev.json
# Staging
pmdaemon start ecosystem.staging.json
# Production
pmdaemon start ecosystem.prod.json
2. Environment Variable Deployment
# Development
NODE_ENV=development pmdaemon start ecosystem.json
# Production
NODE_ENV=production pmdaemon start ecosystem.json
3. Docker-Based Deployment
Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Install PMDaemon
RUN cargo install pmdaemon
COPY ecosystem.json ./
CMD ["pmdaemon", "start", "ecosystem.json"]
docker-compose.yml:
version: '3.8'
services:
app-dev:
build: .
environment:
- NODE_ENV=development
- PORT=3000
- DATABASE_URL=mongodb://mongo:27017/myapp_dev
volumes:
- .:/app
- /app/node_modules
ports:
- "3000:3000"
depends_on:
- mongo
app-prod:
build: .
environment:
- NODE_ENV=production
- PORT=3000
- DATABASE_URL=mongodb://mongo:27017/myapp
ports:
- "3000:3000"
depends_on:
- mongo
restart: unless-stopped
Environment Variable Management
1. Environment Files
.env.development:
NODE_ENV=development
DEBUG=*
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp_dev
REDIS_HOST=localhost
REDIS_PORT=6379
LOG_LEVEL=debug
.env.production:
NODE_ENV=production
DB_HOST=prod-db-cluster
DB_PORT=5432
DB_NAME=myapp
REDIS_HOST=prod-redis
REDIS_PORT=6379
LOG_LEVEL=error
2. Secure Secrets Management
For sensitive data, use external secret management:
{
"apps": [
{
"name": "secure-app",
"script": "server.js",
"env": {
"NODE_ENV": "production",
"DB_PASSWORD_FILE": "/run/secrets/db_password",
"JWT_SECRET_FILE": "/run/secrets/jwt_secret"
}
}
]
}
3. Dynamic Configuration Loading
// config.js
const fs = require('fs');
function loadConfig() {
const env = process.env.NODE_ENV || 'development';
// Load base config
const baseConfig = require('./config.base.json');
// Load environment-specific config
const envConfig = require(`./config.${env}.json`);
// Load secrets from files
if (process.env.DB_PASSWORD_FILE) {
envConfig.database.password = fs.readFileSync(
process.env.DB_PASSWORD_FILE,
'utf8'
).trim();
}
return { ...baseConfig, ...envConfig };
}
module.exports = loadConfig();
Configuration Validation
Environment-Specific Schemas
development.schema.json:
{
"type": "object",
"required": ["name", "script"],
"properties": {
"watch": { "type": "boolean", "default": true },
"instances": { "type": "number", "maximum": 4 },
"max_restarts": { "type": "number", "minimum": 10 }
}
}
production.schema.json:
{
"type": "object",
"required": ["name", "script", "health_check"],
"properties": {
"watch": { "type": "boolean", "const": false },
"instances": { "type": ["number", "string"] },
"max_restarts": { "type": "number", "maximum": 5 },
"health_check": { "type": "object", "required": ["enabled"] }
}
}
Validation Scripts
#!/bin/bash
# validate-config.sh
ENV=${1:-development}
CONFIG_FILE="ecosystem.${ENV}.json"
echo "Validating configuration for environment: $ENV"
# Validate JSON syntax
if ! jq empty "$CONFIG_FILE" 2>/dev/null; then
echo "Error: Invalid JSON syntax in $CONFIG_FILE"
exit 1
fi
# Validate against schema
if ! pmdaemon validate "$CONFIG_FILE" --schema="${ENV}.schema.json"; then
echo "Error: Configuration validation failed"
exit 1
fi
echo "Configuration is valid for $ENV environment"
Best Practices
1. Environment Isolation
- Use separate databases for each environment
- Isolate network configurations
- Use different service accounts/credentials
2. Configuration Management
- Version control all configuration files
- Use environment-specific validation
- Document environment differences
3. Security Considerations
- Never commit secrets to version control
- Use secret management systems in production
- Rotate credentials regularly
4. Testing Strategies
- Test configurations in staging before production
- Validate environment parity
- Use automated deployment pipelines
5. Monitoring and Observability
- Environment-specific monitoring dashboards
- Different alerting thresholds per environment
- Comprehensive logging strategies
Related Documentation
- Ecosystem Files - Complete ecosystem configuration guide
- Best Practices - Configuration best practices
- Security - Security considerations