cube-ms
Version:
Production-ready microservice framework with health monitoring, validation, error handling, and Docker Swarm support
275 lines (248 loc) • 9.7 kB
JavaScript
import dotenv from 'dotenv';
// Load environment variables
dotenv.config();
/**
* Environment configuration with production-safe defaults
* Supports Docker Swarm, Kubernetes, and cloud deployments
*/
export const config = {
// Service Identity (Docker Swarm compatible)
service: {
name: process.env.SERVICE_NAME || process.env.HOSTNAME || 'cube-microservice',
version: process.env.SERVICE_VERSION || process.env.npm_package_version || '1.0.0',
instance: process.env.TASK_SLOT || process.env.CONTAINER_ID || process.env.HOSTNAME || 'unknown',
environment: process.env.NODE_ENV || 'development',
cluster: process.env.CLUSTER_NAME || 'default'
},
// Network Configuration (Docker Swarm overlay networks)
network: {
// Use Docker service name or fallback to localhost
host: process.env.HOST || process.env.SERVICE_HOST || '0.0.0.0',
port: parseInt(process.env.PORT, 10) || 3000,
// Service discovery endpoints
registry: {
enabled: process.env.SERVICE_REGISTRY_ENABLED === 'true',
url: process.env.SERVICE_REGISTRY_URL,
healthCheckInterval: parseInt(process.env.HEALTH_CHECK_INTERVAL, 10) || 30000
}
},
// Database Configuration (Docker Swarm services)
database: {
// MongoDB connection (supports Docker service names)
mongodb: {
url: process.env.MONGODB_URL ||
process.env.LOG_DB_URL ||
(process.env.NODE_ENV === 'production'
? 'mongodb://mongodb:27017' // Docker service name
: 'mongodb://localhost:27017'
),
options: {
maxPoolSize: parseInt(process.env.DB_MAX_POOL_SIZE, 10) || 20,
minPoolSize: parseInt(process.env.DB_MIN_POOL_SIZE, 10) || 1,
maxIdleTimeMS: parseInt(process.env.DB_MAX_IDLE_TIME, 10) || 300000,
serverSelectionTimeoutMS: parseInt(process.env.DB_SERVER_TIMEOUT, 10) || 10000,
heartbeatFrequencyMS: parseInt(process.env.DB_HEARTBEAT_FREQ, 10) || 10000,
retryWrites: process.env.DB_RETRY_WRITES !== 'false',
w: process.env.DB_WRITE_CONCERN || 'majority'
}
}
},
// Logging Configuration
logging: {
level: process.env.LOG_LEVEL || (process.env.NODE_ENV === 'production' ? 'info' : 'debug'),
database: {
enabled: process.env.LOG_DB_ENABLED !== 'false',
maxRecords: parseInt(process.env.LOG_MAX_RECORDS, 10) || 10000,
maxBytes: parseInt(process.env.LOG_MAX_BYTES, 10) || 10485760, // 10MB
ttl: parseInt(process.env.LOG_TTL_HOURS, 10) || 24 * 7 // 7 days
},
console: {
enabled: process.env.LOG_CONSOLE_ENABLED !== 'false',
format: process.env.LOG_FORMAT || 'json', // json or text
colorize: process.env.LOG_COLORIZE === 'true' && process.env.NODE_ENV !== 'production'
},
// CCN Logging Configuration
ccn: {
enabled: process.env.CCN_LOGGING_ENABLED === 'true' || (process.env.NODE_ENV === 'production' && process.env.CCN_LOGGING_ENABLED !== 'false'),
product: process.env.CCN_PRODUCT || process.env.SERVICE_NAME || 'cube-microservice',
serverID: process.env.CCN_SERVER_ID || process.env.HOSTNAME || process.env.CONTAINER_ID || 'unknown',
appID: process.env.CCN_APP_ID || process.env.SERVICE_NAME || 'cube-microservice',
loggingEndpoint: process.env.CCN_LOGGING_ENDPOINT || 'http://logging-service:8080/api/logs',
logLevel: {
startup: process.env.CCN_LOG_LEVEL_STARTUP || 'Level2',
error: process.env.CCN_LOG_LEVEL_ERROR || 'Level1',
success: process.env.CCN_LOG_LEVEL_SUCCESS || 'Level3',
request: process.env.CCN_LOG_LEVEL_REQUEST || 'Level4'
}
}
},
// Security Configuration
security: {
// Request limits
request: {
bodyLimit: process.env.REQUEST_BODY_LIMIT || '10mb',
timeout: parseInt(process.env.REQUEST_TIMEOUT, 10) || 30000,
rateLimitWindow: parseInt(process.env.RATE_LIMIT_WINDOW, 10) || 900000, // 15 minutes
rateLimitMax: parseInt(process.env.RATE_LIMIT_MAX, 10) || 100
},
// CORS configuration
cors: {
enabled: process.env.CORS_ENABLED !== 'false',
origin: process.env.CORS_ORIGIN || false,
credentials: process.env.CORS_CREDENTIALS === 'true'
},
// Helmet security headers
helmet: {
enabled: process.env.SECURITY_HEADERS_ENABLED !== 'false',
contentSecurityPolicy: process.env.CSP_ENABLED !== 'false',
hsts: process.env.HSTS_ENABLED !== 'false'
}
},
// Health Check Configuration
health: {
enabled: process.env.HEALTH_CHECK_ENABLED !== 'false',
timeout: parseInt(process.env.HEALTH_CHECK_TIMEOUT, 10) || 5000,
interval: parseInt(process.env.HEALTH_CHECK_INTERVAL, 10) || 30000,
gracePeriod: parseInt(process.env.HEALTH_GRACE_PERIOD, 10) || 30000,
endpoints: {
liveness: process.env.HEALTH_LIVENESS_PATH || '/health/live',
readiness: process.env.HEALTH_READINESS_PATH || '/health/ready',
full: process.env.HEALTH_FULL_PATH || '/health'
}
},
// Performance Configuration
performance: {
// Cluster mode (PM2 or Docker Swarm)
cluster: {
enabled: process.env.CLUSTER_ENABLED === 'true',
workers: parseInt(process.env.CLUSTER_WORKERS, 10) || 4
},
// Memory limits
memory: {
maxHeapSize: process.env.MAX_HEAP_SIZE,
gcInterval: parseInt(process.env.GC_INTERVAL, 10) || 0,
memoryWarningThreshold: parseInt(process.env.MEMORY_WARNING_MB, 10) || 256
},
// Connection limits
connections: {
maxConcurrent: parseInt(process.env.MAX_CONCURRENT_CONNECTIONS, 10) || 1000,
keepAliveTimeout: parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10) || 65000
}
},
// Graceful Shutdown Configuration
shutdown: {
timeout: parseInt(process.env.SHUTDOWN_TIMEOUT, 10) || 10000,
signals: (process.env.SHUTDOWN_SIGNALS || 'SIGTERM,SIGINT').split(','),
gracePeriod: parseInt(process.env.SHUTDOWN_GRACE_PERIOD, 10) || 5000
},
// Monitoring & Observability
monitoring: {
// Metrics collection
metrics: {
enabled: process.env.METRICS_ENABLED === 'true',
endpoint: process.env.METRICS_ENDPOINT || '/metrics',
interval: parseInt(process.env.METRICS_INTERVAL, 10) || 10000
},
// Tracing (OpenTelemetry)
tracing: {
enabled: process.env.TRACING_ENABLED === 'true',
endpoint: process.env.TRACING_ENDPOINT,
serviceName: process.env.TRACING_SERVICE_NAME || process.env.SERVICE_NAME || 'cube-microservice',
sampleRate: parseFloat(process.env.TRACING_SAMPLE_RATE) || 0.1
},
// APM integration
apm: {
enabled: process.env.APM_ENABLED === 'true',
serverUrl: process.env.APM_SERVER_URL,
secretToken: process.env.APM_SECRET_TOKEN
}
}
};
/**
* Validate configuration for production deployment
*/
export function validateConfig() {
const errors = [];
const warnings = [];
// Required for production
if (config.service.environment === 'production') {
if (!process.env.MONGODB_URL && !process.env.LOG_DB_URL) {
errors.push('MONGODB_URL or LOG_DB_URL must be set in production');
}
if (config.network.host === 'localhost' || config.network.host === '127.0.0.1') {
warnings.push('Consider using 0.0.0.0 for Docker container deployments');
}
if (!process.env.SERVICE_NAME) {
warnings.push('SERVICE_NAME should be set for better service identification');
}
}
// Security validations
if (config.security.cors.origin === '*' && config.service.environment === 'production') {
warnings.push('CORS_ORIGIN=* is not recommended for production');
}
return { errors, warnings, isValid: errors.length === 0 };
}
/**
* Get Docker Swarm specific configuration
*/
export function getSwarmConfig() {
return {
// Docker Swarm service discovery
serviceName: process.env.SERVICE_NAME,
taskId: process.env.TASK_ID,
taskSlot: process.env.TASK_SLOT,
nodeId: process.env.NODE_ID,
networkId: process.env.NETWORK_ID,
// Swarm networking
vip: process.env.SERVICE_VIP,
publishedPort: process.env.PUBLISHED_PORT,
targetPort: process.env.TARGET_PORT,
// Service constraints
placement: {
constraints: process.env.PLACEMENT_CONSTRAINTS,
preferences: process.env.PLACEMENT_PREFERENCES
},
// Resource limits
resources: {
limits: {
cpus: process.env.RESOURCE_LIMIT_CPUS,
memory: process.env.RESOURCE_LIMIT_MEMORY
},
reservations: {
cpus: process.env.RESOURCE_RESERVE_CPUS,
memory: process.env.RESOURCE_RESERVE_MEMORY
}
}
};
}
/**
* Environment-specific overrides
*/
export function getEnvironmentOverrides() {
const env = config.service.environment;
const overrides = {
development: {
logging: { level: 'debug', console: { colorize: true } },
security: { helmet: { contentSecurityPolicy: false } },
health: { interval: 10000 }
},
test: {
logging: { database: { enabled: false }, console: { enabled: false } },
health: { enabled: false },
database: { mongodb: { url: 'mongodb://localhost:27017/test' } }
},
staging: {
logging: { level: 'info' },
security: { cors: { origin: process.env.STAGING_CORS_ORIGIN } },
monitoring: { metrics: { enabled: true } }
},
production: {
logging: { level: 'warn', console: { colorize: false } },
security: { helmet: { enabled: true, hsts: true } },
monitoring: { metrics: { enabled: true }, tracing: { enabled: true } },
performance: { cluster: { enabled: true } }
}
};
return overrides[env] || {};
}
export default config;