Running Node.js Apps as systemd Services on Linux: A Beginner's Guide

Table of contents

Managing background processes on Linux can be tricky without the right tools. If you’re deploying a Node.js application and want it to start on boot, recover from crashes, and log efficiently, then systemd
is your best friend.
In this post, we’ll walk through how to run a Node.js app as a systemd
service—with an automation script included.
What is systemd?
systemd
is the default init system in most modern Linux distributions. It’s responsible for booting the system and managing services (also called units). It can:
Start services at boot time
Monitor and restart them on failure
Manage dependencies between services
Log output via
journalctl
For Node.js developers, this means your app can become a first-class citizen of the Linux OS.
Why Use systemd for Node.js?
Running Node.js apps using systemd
brings several advantages:
Automatic Startup: Start your app every time the server reboots.
Failure Recovery: Restart it if it crashes—automatically.
System-wide Logging: Log output to
journalctl
, making debugging easier.Isolation: Manage your app as a standalone service, fully independent from your shell session.
Step-by-Step: Creating the Node.js Service
Step 1: Create Your Node.js Server
Start by writing a basic HTTP server:
mkdir -p /root/code/node
cd /root/code/node
nano server.js
Paste the following:
const http = require('http');
const hostname = '127.0.0.1';
const port = 3311;
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Node app is running!');
}).listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Test it with:
node server.js
Visit http://127.0.0.1:3311
to confirm it's running.
Step 2: Create the systemd Service File
Navigate to the systemd
directory:
cd /etc/systemd/system/
nano node.service
Add this content:
[Unit]
Description=Start Node.js App
After=network.target
[Service]
ExecStart=/usr/bin/node /root/code/node/server.js
WorkingDirectory=/root/code/node
Restart=on-failure
RestartSec=5
KillMode=control-group
[Install]
WantedBy=multi-user.target
Make sure the ExecStart
path matches your Node.js binary (which node
).
Step 3: Enable and Start the Service
systemctl daemon-reload
systemctl enable node.service
systemctl start node.service
Check the status:
systemctl status node.service
You should see active (running)
if all goes well.
Step 4: View Logs with journalctl
To tail logs in real time:
journalctl -u node.service -f
To see all historical logs:
journalctl -u node.service
Step 5: Test Automatic Restart
Simulate a crash:
- Find the PID:
ps aux | grep server.js
- Kill it:
sudo kill -9 <PID>
- Watch systemd restart it:
systemctl status node.service
The service should be automatically restarted thanks to the Restart=on-failure
directive.
Automate It with a Shell Script
Save time by using this prebuilt script that sets up everything in seconds.
#!/bin/bash
NODE_DIR="/root/code/node"
SERVICE_FILE="/etc/systemd/system/node.service"
NODE_PATH=$(which node)
echo "Creating Node.js server..."
mkdir -p $NODE_DIR
cat > $NODE_DIR/server.js <<EOF
const http = require('http');
const hostname = '127.0.0.1';
const port = 3311;
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Node app is running!');
}).listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
EOF
echo "Creating systemd service..."
cat > $SERVICE_FILE <<EOF
[Unit]
Description=Start Node.js App
After=network.target
[Service]
ExecStart=$NODE_PATH $NODE_DIR/server.js
WorkingDirectory=$NODE_DIR
Restart=on-failure
KillMode=control-group
[Install]
WantedBy=multi-user.target
EOF
echo "Reloading systemd and enabling service..."
systemctl daemon-reload
systemctl enable node.service
systemctl start node.service
echo "Node.js systemd service status:"
systemctl status node.service --no-pager
Make it executable and run:
chmod +x setup_node_systemd.sh
sudo ./setup_node_systemd.sh
Summary
Integrating your Node.js applications with systemd
gives you production-grade stability and control—without needing third-party process managers like PM2. You’ll benefit from automatic recovery, centralized logging, and simplified deployment.
Whether you're deploying to the cloud, a VPS, or your local server, this approach keeps your Node apps running reliably.
Subscribe to my newsletter
Read articles from Md Saif Zaman directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
