Keep It Running After a Crash
PM2 / systemd / Process Managers
On VMs, a process manager handles restarts, log rotation, and clustering when you are not using Docker.
What you'll learn
- Install PM2 and use ecosystem.config
- Write a systemd unit with Restart=always
- Run as a non-root user
In containers, the orchestrator restarts crashed processes. On a plain VM you need a process manager — PM2 if you want clustering and logs out of the box, or systemd if you want zero extra dependencies.
PM2
npm i -g pm2 // ecosystem.config.cjs
module.exports = {
apps: [
{
name: 'api',
script: 'dist/index.js',
instances: 'max',
exec_mode: 'cluster',
env: { NODE_ENV: 'production', PORT: 3000 },
},
],
}; pm2 start ecosystem.config.cjs
pm2 startup # generate the init script
pm2 save # persist running list
pm2 logs api # tail logs instances: 'max' forks one worker per CPU and load-balances over them — Fastify on cluster
mode is roughly linear with cores for stateless workloads.
systemd
If you prefer no extra runtime, a systemd unit is enough.
# /etc/systemd/system/api.service
[Unit]
Description=My Fastify API
After=network.target
[Service]
Type=simple
User=app
WorkingDirectory=/srv/api
ExecStart=/usr/bin/node dist/index.js
Restart=always
RestartSec=5
Environment=NODE_ENV=production
Environment=PORT=3000
[Install]
WantedBy=multi-user.target sudo systemctl daemon-reload
sudo systemctl enable --now api
journalctl -u api -f Run as a non-root user (User=app) so a code exploit can’t reach the rest of the box.