Files
flyer-crawler.projectium.com/ecosystem.dev.config.cjs
Torben Sorensen d03900cefe
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 19m4s
set PST as common time zone for log matching ease
2026-01-22 23:38:45 -08:00

177 lines
6.9 KiB
JavaScript

// ecosystem.dev.config.cjs
// ============================================================================
// DEVELOPMENT PM2 CONFIGURATION
// ============================================================================
// This file mirrors the production ecosystem.config.cjs but with settings
// appropriate for the development environment inside the dev container.
//
// Key differences from production:
// - Single instance for API (not cluster mode) to allow debugger attachment
// - tsx watch mode for hot reloading
// - Development-specific environment variables
// - Logs written to /var/log/pm2 for Logstash integration (ADR-050)
//
// Usage:
// pm2 start ecosystem.dev.config.cjs
// pm2 logs # View all logs
// pm2 logs flyer-crawler-api-dev # View API logs only
// pm2 restart all # Restart all processes
// pm2 delete all # Stop all processes
//
// Related:
// - ecosystem.config.cjs (production configuration)
// - docs/adr/0014-linux-only-platform.md
// - docs/adr/0050-postgresql-function-observability.md
// ============================================================================
// --- Environment Variable Validation ---
// In dev, we warn but don't fail - variables come from compose.dev.yml
const requiredVars = ['DB_HOST', 'JWT_SECRET'];
const missingVars = requiredVars.filter((key) => !process.env[key]);
if (missingVars.length > 0) {
console.warn(
'\n[ecosystem.dev.config.cjs] WARNING: The following environment variables are MISSING:',
);
missingVars.forEach((key) => console.warn(` - ${key}`));
console.warn(
'[ecosystem.dev.config.cjs] These should be set in compose.dev.yml or .env.local\n',
);
} else {
console.log('[ecosystem.dev.config.cjs] Required environment variables are present.');
}
// --- Shared Environment Variables ---
// These come from compose.dev.yml environment section
const sharedEnv = {
// Timezone: PST (America/Los_Angeles) for consistent log timestamps
TZ: process.env.TZ || 'America/Los_Angeles',
NODE_ENV: 'development',
DB_HOST: process.env.DB_HOST || 'postgres',
DB_PORT: process.env.DB_PORT || '5432',
DB_USER: process.env.DB_USER || 'postgres',
DB_PASSWORD: process.env.DB_PASSWORD || 'postgres',
DB_NAME: process.env.DB_NAME || 'flyer_crawler_dev',
REDIS_URL: process.env.REDIS_URL || 'redis://redis:6379',
REDIS_HOST: process.env.REDIS_HOST || 'redis',
REDIS_PORT: process.env.REDIS_PORT || '6379',
FRONTEND_URL: process.env.FRONTEND_URL || 'https://localhost',
JWT_SECRET: process.env.JWT_SECRET || 'dev-jwt-secret-change-in-production',
WORKER_LOCK_DURATION: process.env.WORKER_LOCK_DURATION || '120000',
// Sentry/Bugsink (ADR-015)
SENTRY_DSN: process.env.SENTRY_DSN,
SENTRY_ENVIRONMENT: process.env.SENTRY_ENVIRONMENT || 'development',
SENTRY_ENABLED: process.env.SENTRY_ENABLED || 'true',
SENTRY_DEBUG: process.env.SENTRY_DEBUG || 'true',
// Optional API keys (may not be set in dev)
GEMINI_API_KEY: process.env.GEMINI_API_KEY,
GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY,
GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,
GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,
};
module.exports = {
apps: [
// =========================================================================
// API SERVER (Development)
// =========================================================================
// Single instance with tsx watch for hot reloading.
// Unlike production, we don't use cluster mode to allow:
// - Debugger attachment
// - Simpler log output
// - Hot reloading via tsx watch
{
name: 'flyer-crawler-api-dev',
script: './node_modules/.bin/tsx',
args: 'watch server.ts',
cwd: '/app',
watch: false, // tsx watch handles this
instances: 1, // Single instance for debugging
exec_mode: 'fork', // Fork mode (not cluster) for debugging
max_memory_restart: '1G', // More generous in dev
kill_timeout: 5000,
// PM2 log configuration (ADR-050 - Logstash integration)
output: '/var/log/pm2/api-out.log',
error: '/var/log/pm2/api-error.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true,
// Restart configuration
max_restarts: 10,
exp_backoff_restart_delay: 500,
min_uptime: '5s',
// Environment
env: {
...sharedEnv,
PORT: '3001',
},
},
// =========================================================================
// BACKGROUND WORKER (Development)
// =========================================================================
// Processes background jobs (flyer processing, cleanup, etc.)
// Runs as a separate process like in production.
{
name: 'flyer-crawler-worker-dev',
script: './node_modules/.bin/tsx',
args: 'watch src/services/worker.ts',
cwd: '/app',
watch: false, // tsx watch handles this
instances: 1,
exec_mode: 'fork',
max_memory_restart: '1G',
kill_timeout: 10000, // Workers need more time to finish jobs
// PM2 log configuration (ADR-050)
output: '/var/log/pm2/worker-out.log',
error: '/var/log/pm2/worker-error.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true,
// Restart configuration
max_restarts: 10,
exp_backoff_restart_delay: 500,
min_uptime: '5s',
// Environment
env: {
...sharedEnv,
},
},
// =========================================================================
// VITE FRONTEND DEV SERVER (Development)
// =========================================================================
// Vite dev server for frontend hot module replacement.
// Listens on 5173 and is proxied by nginx to 443.
{
name: 'flyer-crawler-vite-dev',
script: './node_modules/.bin/vite',
args: '--host',
cwd: '/app',
watch: false, // Vite handles its own watching
instances: 1,
exec_mode: 'fork',
max_memory_restart: '2G', // Vite can use significant memory
kill_timeout: 5000,
// PM2 log configuration (ADR-050)
output: '/var/log/pm2/vite-out.log',
error: '/var/log/pm2/vite-error.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true,
// Restart configuration
max_restarts: 10,
exp_backoff_restart_delay: 500,
min_uptime: '5s',
// Environment
env: {
// Timezone: PST (America/Los_Angeles) for consistent log timestamps
TZ: process.env.TZ || 'America/Los_Angeles',
NODE_ENV: 'development',
// Vite-specific env vars (VITE_ prefix)
VITE_SENTRY_DSN: process.env.VITE_SENTRY_DSN,
VITE_SENTRY_ENVIRONMENT: process.env.VITE_SENTRY_ENVIRONMENT || 'development',
VITE_SENTRY_ENABLED: process.env.VITE_SENTRY_ENABLED || 'true',
VITE_SENTRY_DEBUG: process.env.VITE_SENTRY_DEBUG || 'true',
},
},
],
};