// ecosystem.config.cjs // This file is the standard way to configure applications for PM2. // It allows us to define all the settings for our application in one place. // The .cjs extension is required because the project's package.json has "type": "module". // --- Environment Variable Validation --- const requiredSecrets = ['DB_HOST', 'JWT_SECRET', 'GEMINI_API_KEY']; const missingSecrets = requiredSecrets.filter(key => !process.env[key]); if (missingSecrets.length > 0) { console.warn('\n[ecosystem.config.cjs] ⚠️ WARNING: The following environment variables are MISSING in the shell:'); missingSecrets.forEach(key => console.warn(` - ${key}`)); console.warn('[ecosystem.config.cjs] The application may crash if these are required for startup.\n'); process.exit(1); // Fail fast so PM2 doesn't attempt to start a broken app } else { console.log('[ecosystem.config.cjs] ✅ Critical environment variables are present.'); } module.exports = { apps: [ { // --- API Server --- name: 'flyer-crawler-api', // Note: The process names below are referenced in .gitea/workflows/ for status checks. script: './node_modules/.bin/tsx', args: 'server.ts', max_memory_restart: '500M', // Restart Logic max_restarts: 40, exp_backoff_restart_delay: 100, min_uptime: '10s', // Production Environment Settings env_production: { NODE_ENV: 'production', name: 'flyer-crawler-api', cwd: '/var/www/flyer-crawler.projectium.com', DB_HOST: process.env.DB_HOST, DB_USER: process.env.DB_USER, DB_PASSWORD: process.env.DB_PASSWORD, DB_NAME: process.env.DB_NAME, REDIS_URL: process.env.REDIS_URL, REDIS_PASSWORD: process.env.REDIS_PASSWORD, FRONTEND_URL: process.env.FRONTEND_URL, JWT_SECRET: process.env.JWT_SECRET, GEMINI_API_KEY: process.env.GEMINI_API_KEY, GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY, SMTP_HOST: process.env.SMTP_HOST, SMTP_PORT: process.env.SMTP_PORT, SMTP_SECURE: process.env.SMTP_SECURE, SMTP_USER: process.env.SMTP_USER, SMTP_PASS: process.env.SMTP_PASS, SMTP_FROM_EMAIL: process.env.SMTP_FROM_EMAIL, }, // Test Environment Settings env_test: { NODE_ENV: 'test', name: 'flyer-crawler-api-test', cwd: '/var/www/flyer-crawler-test.projectium.com', DB_HOST: process.env.DB_HOST, DB_USER: process.env.DB_USER, DB_PASSWORD: process.env.DB_PASSWORD, DB_NAME: process.env.DB_NAME, REDIS_URL: process.env.REDIS_URL, REDIS_PASSWORD: process.env.REDIS_PASSWORD, FRONTEND_URL: process.env.FRONTEND_URL, JWT_SECRET: process.env.JWT_SECRET, GEMINI_API_KEY: process.env.GEMINI_API_KEY, GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY, SMTP_HOST: process.env.SMTP_HOST, SMTP_PORT: process.env.SMTP_PORT, SMTP_SECURE: process.env.SMTP_SECURE, SMTP_USER: process.env.SMTP_USER, SMTP_PASS: process.env.SMTP_PASS, SMTP_FROM_EMAIL: process.env.SMTP_FROM_EMAIL, }, // Development Environment Settings env_development: { NODE_ENV: 'development', name: 'flyer-crawler-api-dev', watch: true, ignore_watch: ['node_modules', 'logs', '*.log', 'flyer-images', '.git'], DB_HOST: process.env.DB_HOST, DB_USER: process.env.DB_USER, DB_PASSWORD: process.env.DB_PASSWORD, DB_NAME: process.env.DB_NAME, REDIS_URL: process.env.REDIS_URL, REDIS_PASSWORD: process.env.REDIS_PASSWORD, FRONTEND_URL: process.env.FRONTEND_URL, JWT_SECRET: process.env.JWT_SECRET, GEMINI_API_KEY: process.env.GEMINI_API_KEY, GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY, SMTP_HOST: process.env.SMTP_HOST, SMTP_PORT: process.env.SMTP_PORT, SMTP_SECURE: process.env.SMTP_SECURE, SMTP_USER: process.env.SMTP_USER, SMTP_PASS: process.env.SMTP_PASS, SMTP_FROM_EMAIL: process.env.SMTP_FROM_EMAIL, }, }, { // --- General Worker --- name: 'flyer-crawler-worker', script: './node_modules/.bin/tsx', args: 'src/services/worker.ts', max_memory_restart: '1G', // Restart Logic max_restarts: 40, exp_backoff_restart_delay: 100, min_uptime: '10s', // Production Environment Settings env_production: { NODE_ENV: 'production', name: 'flyer-crawler-worker', cwd: '/var/www/flyer-crawler.projectium.com', DB_HOST: process.env.DB_HOST, DB_USER: process.env.DB_USER, DB_PASSWORD: process.env.DB_PASSWORD, DB_NAME: process.env.DB_NAME, REDIS_URL: process.env.REDIS_URL, REDIS_PASSWORD: process.env.REDIS_PASSWORD, FRONTEND_URL: process.env.FRONTEND_URL, JWT_SECRET: process.env.JWT_SECRET, GEMINI_API_KEY: process.env.GEMINI_API_KEY, GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY, SMTP_HOST: process.env.SMTP_HOST, SMTP_PORT: process.env.SMTP_PORT, SMTP_SECURE: process.env.SMTP_SECURE, SMTP_USER: process.env.SMTP_USER, SMTP_PASS: process.env.SMTP_PASS, SMTP_FROM_EMAIL: process.env.SMTP_FROM_EMAIL, }, // Test Environment Settings env_test: { NODE_ENV: 'test', name: 'flyer-crawler-worker-test', cwd: '/var/www/flyer-crawler-test.projectium.com', DB_HOST: process.env.DB_HOST, DB_USER: process.env.DB_USER, DB_PASSWORD: process.env.DB_PASSWORD, DB_NAME: process.env.DB_NAME, REDIS_URL: process.env.REDIS_URL, REDIS_PASSWORD: process.env.REDIS_PASSWORD, FRONTEND_URL: process.env.FRONTEND_URL, JWT_SECRET: process.env.JWT_SECRET, GEMINI_API_KEY: process.env.GEMINI_API_KEY, GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY, SMTP_HOST: process.env.SMTP_HOST, SMTP_PORT: process.env.SMTP_PORT, SMTP_SECURE: process.env.SMTP_SECURE, SMTP_USER: process.env.SMTP_USER, SMTP_PASS: process.env.SMTP_PASS, SMTP_FROM_EMAIL: process.env.SMTP_FROM_EMAIL, }, // Development Environment Settings env_development: { NODE_ENV: 'development', name: 'flyer-crawler-worker-dev', watch: true, ignore_watch: ['node_modules', 'logs', '*.log', 'flyer-images', '.git'], DB_HOST: process.env.DB_HOST, DB_USER: process.env.DB_USER, DB_PASSWORD: process.env.DB_PASSWORD, DB_NAME: process.env.DB_NAME, REDIS_URL: process.env.REDIS_URL, REDIS_PASSWORD: process.env.REDIS_PASSWORD, FRONTEND_URL: process.env.FRONTEND_URL, JWT_SECRET: process.env.JWT_SECRET, GEMINI_API_KEY: process.env.GEMINI_API_KEY, GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY, SMTP_HOST: process.env.SMTP_HOST, SMTP_PORT: process.env.SMTP_PORT, SMTP_SECURE: process.env.SMTP_SECURE, SMTP_USER: process.env.SMTP_USER, SMTP_PASS: process.env.SMTP_PASS, SMTP_FROM_EMAIL: process.env.SMTP_FROM_EMAIL, }, }, { // --- Analytics Worker --- name: 'flyer-crawler-analytics-worker', script: './node_modules/.bin/tsx', args: 'src/services/worker.ts', max_memory_restart: '1G', // Restart Logic max_restarts: 40, exp_backoff_restart_delay: 100, min_uptime: '10s', // Production Environment Settings env_production: { NODE_ENV: 'production', name: 'flyer-crawler-analytics-worker', cwd: '/var/www/flyer-crawler.projectium.com', DB_HOST: process.env.DB_HOST, DB_USER: process.env.DB_USER, DB_PASSWORD: process.env.DB_PASSWORD, DB_NAME: process.env.DB_NAME, REDIS_URL: process.env.REDIS_URL, REDIS_PASSWORD: process.env.REDIS_PASSWORD, FRONTEND_URL: process.env.FRONTEND_URL, JWT_SECRET: process.env.JWT_SECRET, GEMINI_API_KEY: process.env.GEMINI_API_KEY, GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY, SMTP_HOST: process.env.SMTP_HOST, SMTP_PORT: process.env.SMTP_PORT, SMTP_SECURE: process.env.SMTP_SECURE, SMTP_USER: process.env.SMTP_USER, SMTP_PASS: process.env.SMTP_PASS, SMTP_FROM_EMAIL: process.env.SMTP_FROM_EMAIL, }, // Test Environment Settings env_test: { NODE_ENV: 'test', name: 'flyer-crawler-analytics-worker-test', cwd: '/var/www/flyer-crawler-test.projectium.com', DB_HOST: process.env.DB_HOST, DB_USER: process.env.DB_USER, DB_PASSWORD: process.env.DB_PASSWORD, DB_NAME: process.env.DB_NAME, REDIS_URL: process.env.REDIS_URL, REDIS_PASSWORD: process.env.REDIS_PASSWORD, FRONTEND_URL: process.env.FRONTEND_URL, JWT_SECRET: process.env.JWT_SECRET, GEMINI_API_KEY: process.env.GEMINI_API_KEY, GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY, SMTP_HOST: process.env.SMTP_HOST, SMTP_PORT: process.env.SMTP_PORT, SMTP_SECURE: process.env.SMTP_SECURE, SMTP_USER: process.env.SMTP_USER, SMTP_PASS: process.env.SMTP_PASS, SMTP_FROM_EMAIL: process.env.SMTP_FROM_EMAIL, }, // Development Environment Settings env_development: { NODE_ENV: 'development', name: 'flyer-crawler-analytics-worker-dev', watch: true, ignore_watch: ['node_modules', 'logs', '*.log', 'flyer-images', '.git'], DB_HOST: process.env.DB_HOST, DB_USER: process.env.DB_USER, DB_PASSWORD: process.env.DB_PASSWORD, DB_NAME: process.env.DB_NAME, REDIS_URL: process.env.REDIS_URL, REDIS_PASSWORD: process.env.REDIS_PASSWORD, FRONTEND_URL: process.env.FRONTEND_URL, JWT_SECRET: process.env.JWT_SECRET, GEMINI_API_KEY: process.env.GEMINI_API_KEY, GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY, SMTP_HOST: process.env.SMTP_HOST, SMTP_PORT: process.env.SMTP_PORT, SMTP_SECURE: process.env.SMTP_SECURE, SMTP_USER: process.env.SMTP_USER, SMTP_PASS: process.env.SMTP_PASS, SMTP_FROM_EMAIL: process.env.SMTP_FROM_EMAIL, }, }, ], };