// Single source of truth for runtime config is TSSBOT/.env. start_bot.py // loads it directly (load_dotenv(_HERE / ".env")). Do NOT add `env:` blocks // below or `require('dotenv')` here — either would create a second config // source that can silently shadow .env, and the dotenv require would fail // outright on hosts that don't have node_modules/ installed in TSSBOT. const DEPLOY_PATH = __dirname; // Both bots share one venv at BOTS/SHARED/.venv, built from // SHARED/requirements.txt (both bots also share BOTS/SHARED for code). const PY_INTERPRETER = `${DEPLOY_PATH}/../SHARED/.venv/bin/python`; // Crash-loop governor: after max_restarts attempts that each fail to stay up // min_uptime ms, PM2 marks the app `errored` and stops relaunching it, instead // of restarting forever and pegging the CPU. See SREBOT/ecosystem.config.js. const RESTART_POLICY = { max_restarts: 10, min_uptime: 10000, exp_backoff_restart_delay: 200, }; module.exports = { apps: [ // Discord Bot { name: 'tssbot', ...RESTART_POLICY, script: 'start_bot.py', interpreter: PY_INTERPRETER, cwd: DEPLOY_PATH, instances: 1, autorestart: true, watch: false, max_memory_restart: '8000M', log_file: './logs/bot_combined.log', out_file: './logs/bot_out.log', error_file: './logs/bot_error.log', log_date_format: 'YYYY-MM-DD HH:mm:ss Z', merge_logs: true, kill_timeout: 5000, restart_delay: 3000 } // tssbot-api and tssbot-web will be added here once TSSBOT/server.js and // TSSBOT/web/server.js exist. They should read TSSBOT_API_PORT and // TSSBOT_WEB_PORT from .env (mirroring the SREBOT naming convention). ] };