ecosystem.config.cjs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // pm2 process config for daveo-radio.
  2. //
  3. // CommonJS (.cjs) on purpose: package.json has "type": "module", so a plain
  4. // ecosystem.config.js would be parsed as ESM and `module.exports` would throw.
  5. // pm2 reads .cjs fine.
  6. //
  7. // IMPORTANT — build first. Unlike chess-io (which renders templates at
  8. // runtime), this app serves the built bundle in app/, which is gitignored.
  9. // pm2 does NOT build. So on the server, before starting or after any pull:
  10. //
  11. // npm install # full install -- the build needs the devDeps
  12. // # (esbuild, bootstrap, handlebars)
  13. // npm run build # src/ -> app/
  14. // pm2 start ecosystem.config.cjs # first time
  15. // pm2 logs radio --lines 5 # confirm basePath":"/radio"
  16. // pm2 save # remember across restarts
  17. // pm2 startup # prints a sudo command to enable on boot
  18. //
  19. // Redeploy of new code:
  20. // git pull && npm install && npm run build && pm2 restart radio
  21. //
  22. module.exports = {
  23. apps: [
  24. {
  25. name: 'radio',
  26. script: 'app.js',
  27. cwd: __dirname,
  28. // Secrets / extra config come from a gitignored .env on the server
  29. // (LASTFM_API_KEY, and REDIS_URL if you enable it). Node reads it into
  30. // process.env; the inline env below still wins for anything set in both,
  31. // so the operational config here can't be overridden by a stale .env.
  32. // --env-file-if-exists needs Node 22.9+. On older Node, drop this line
  33. // and put LASTFM_API_KEY in the env block below instead.
  34. node_args: '--env-file-if-exists=.env',
  35. // Single process, fork mode -- NOT cluster. Per-connection chat state
  36. // (nicknames, presence) lives in memory in one process via socket.data;
  37. // multiple workers would each hold a different slice and socket.io would
  38. // need a shared adapter + sticky sessions. If you ever DO want to scale
  39. // out, set REDIS_URL (enables the socket.io Redis adapter) and raise
  40. // instances -- not before.
  41. instances: 1,
  42. exec_mode: 'fork',
  43. env: {
  44. NODE_ENV: 'production',
  45. PORT: 3000,
  46. BASE_PATH: '/radio',
  47. TRUST_PROXY: 1,
  48. // Icecast. Must be https on a TLS page (mixed content is blocked).
  49. STREAM_URL: 'https://stream.davidawindham.com/stream',
  50. STREAM_STATUS_URL: 'https://stream.davidawindham.com/status-json.xsl',
  51. STREAM_MOUNT: '/stream',
  52. // LASTFM_API_KEY: set it in .env on the server (see node_args above).
  53. // Unset => the sidebar lists just stay empty; the app still runs.
  54. LASTFM_USER: 'windhamdavid',
  55. // DAW_ORIGIN is intentionally omitted -- it is a local-dev-only shim for
  56. // the shared chrome and must stay UNSET in production, where Apache
  57. // serves /embed from the WordPress docroot.
  58. },
  59. },
  60. ],
  61. };