All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 19m4s
177 lines
6.9 KiB
JavaScript
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',
|
|
},
|
|
},
|
|
],
|
|
};
|