Skip to content

Automatically start at boot PM2 & Systemd

Russ Goldin edited this page May 4, 2026 · 10 revisions

PM2, Systemd

Prerequisites: nodejs-poolController v9+ requires Node.js >= 20. Verify with node -v before proceeding. See the Quick Start Guide for installation instructions.

Note on paths: Raspberry Pi OS no longer uses a default pi username (changed in April 2022). Throughout this guide, replace /home/<your-user>/ with your actual home directory. Run echo $HOME to confirm your path.

PM2

Thanks to @rerouted How to get PM2 installed and running poolController on RPi or Linux

Environment File method

  1. Install PM2 with npm install -g pm2
  2. Quit nodejs-poolController if its running.
  3. Put the script below in your home directory and call it ecosystem.config.js. If you do not need all three apps (REM, dashPanel, nodejs-poolController), simply delete the sections between/including the {} for the app that you do not want to start.
  4. Important: Update all "cwd" paths to match your actual home directory (e.g., /home/michael/nodejs-poolController).
  5. pm2 start ecosystem.config.js
  6. pm2 save
  7. Run pm2 ls to see your app(s) running with pm2. It will show uptime of the app and reset counter. pm2 monit will bring up a UI for monitoring the same.
  8. Type pm2 startup If you want pm2 to auto-start at boot (recommended). This command will give you a command based on your platform to run so pm2 starts on its own. Make sure you follow the directions and paste the given command back into your command line. pm2 unstartup will reverse this behavior.
    • Optional, but highly recommended. Install logrotate to make sure that your logs don't consume all of your disk space.

The below scripts use pm2 features for startup/restart strategies and are current for njsPC v9.0+.

  • pm2 will only watch directories with source files (whitelist) instead of excluding directories with files that change
  • restart delay is set at 10s
  • watch_delay will restart the app within 5s of seeing source files changed
  • the scripts will recompile the app each and every time it starts (uses npm start which runs npm run build && node dist/app.js)

Tip: If you want to skip recompilation on every restart (e.g., to reduce SD card writes), change "args": ["start"] to "args": ["run", "start:cached"] for the njsPC entry. This runs the previously-compiled code directly. You'll need to manually run npm run build after pulling updates.

module.exports = {
  apps : [
    {
      "name": "REM",
      "script": "npm",
      "args": [
        "start"
      ],
      "cwd": "/home/<your-user>/relayEquipmentManager",
      "restart_delay": 10000,
      "watch": [
        "boards",
        "config",
        "connections",
        "devices",
        "gpio",
        "i2c-bus",
        "logger",
        "pages",
        "pinouts",
        "spi-adc",
        "web",
        "package.json"
      ],
      "watch_delay": 5000,
      "kill_timeout": 15000
    },
    {
      "name": "dashPanel",
      "script": "npm",
      "args": [
        "start"
      ],
      "cwd": "/home/<your-user>/nodejs-poolController-dashPanel",
      "restart_delay": 10000,
      "watch": [
        "pages",
        "scripts",
        "server",
        "package.json"
      ],
      "watch_delay": 5000,
      "kill_timeout": 15000
    },
    {
      "name": "njsPC",
      "script": "npm",
      "args": [
        "start"
      ],
      "cwd": "/home/<your-user>/nodejs-poolController",
      "restart_delay": 10000,
      "watch": [
        "config",
        "controller",
        "logger",
        "web",
        "package.json"
      ],
      "watch_delay": 5000,
      "kill_timeout": 15000
    }
  ]
};

Troubleshooting PM2 Path Issues

From @FlaMike - https://github.com/tagyoureit/nodejs-poolController/discussions/801#discussioncomment-7809175

The "cwd" paths in ecosystem.config.js must match your actual home directory. If they don't, PM2 will fail with PID errors.

If you started PM2 with incorrect paths, clean up with:

pm2 stop all
pm2 delete all
pm2 unstartup
pm2 kill
npm remove pm2 -g
rm -rf ~/.pm2

Then reinstall PM2 and ensure your ecosystem.config.js has the correct paths before running pm2 start.

Logs

pm2 logs or pm2 monit is useful for looking at the console logs of your app(s) for troubleshooting.

Systemd

Systemd is an alternative to PM2 that uses the OS init system directly. It's lighter weight and doesn't require a separate process manager.

Setup

Create the service file:

sudo vi /etc/systemd/system/poolController.service

Paste the following, adjusting User, WorkingDirectory, and the node path for your system:

[Unit]
Description=NodeJS Pool Controller
Documentation=https://github.com/tagyoureit/nodejs-poolController/
After=network.target

[Service]
Environment=NODE_ENV=production
Type=simple
User=<your-user>
WorkingDirectory=/home/<your-user>/nodejs-poolController
ExecStart=/usr/bin/node dist/app.js
Restart=on-failure
RestartSec=15s

[Install]
WantedBy=multi-user.target

Finding your node path: Run which node to get the correct ExecStart path. Common locations:

  • /usr/bin/node (system package manager / nodesource)
  • /usr/local/bin/node (manual install)
  • /home/<your-user>/.nvm/versions/node/v20.x.x/bin/node (nvm — not recommended for systemd, use absolute path)

Important: The systemd unit runs node dist/app.js directly, which requires the TypeScript to already be compiled. Run npm run build in the nodejs-poolController directory before starting the service for the first time, and after any code updates (git pull).

Then run these commands:

sudo systemctl daemon-reload
sudo systemctl enable poolController
sudo systemctl start poolController

To check the status of the service:

systemctl status poolController

To tail the log:

sudo journalctl -o cat -n 2500 -f -u poolController

To stop, restart or disable the service, use the appropriate systemctl command:

sudo systemctl stop poolController
sudo systemctl restart poolController
sudo systemctl disable poolController

Docker

For Docker-based deployments, see the Docker wiki page.

Clone this wiki locally