UNPKG

cube-ms

Version:

Production-ready microservice framework with health monitoring, validation, error handling, and Docker Swarm support

275 lines (248 loc) 9.7 kB
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;