Run node.js service with systemd
Node.js as a running service is becoming more and more popular these days. One of the issues many developers face is how to ensure their node.js service starts automatically, and more importantly how to keep it running should it crash. Previously one had to install modules such as forever, and then create some auto-start script to start the daemon when the server booted.
Most Linux systems have recently switched to using systemd, which makes this process a lot simpler and more efficient, and means that we do not need forever
any more.
Create the node.js server
For this example we will use a slightly modified “web server” of the example from the Node.js website:
const http = require('http');
const hostname = '0.0.0.0'; // listen on all ports
const port = 1337;
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end("Hello World\n");
}).listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
We will save this file (for example) as /opt/nodeserver/server.js
. Verify the node server works
node /opt/nodeserver/server.js
Server running at http://0.0.0.0:1337/
Assuming it works, we will now create a systemd file to start this server as a service.
Systemd
Create the service file
Create /etc/systemd/system/nodeserver.service
[Unit]
Description=Node.js Example Server
#Requires=After=mysql.service # Requires the mysql service to run first
[Service]
ExecStart=/usr/local/bin/node /opt/nodeserver/server.js
# Required on some systems
#WorkingDirectory=/opt/nodeserver
Restart=always
# Restart service after 10 seconds if node service crashes
RestartSec=10
# Output to journal
StandardOutput=journal
StandardError=journal
SyslogIdentifier=nodejs-example
#User=<alternate user>
#Group=<alternate group>
Environment=NODE_ENV=production PORT=1337
[Install]
WantedBy=multi-user.target
Enable the service
systemctl enable nodeserver.service
Created symlink from /etc/systemd/system/multi-user.target.wants/nodeserver.service to /etc/systemd/system/nodeserver.service.
Start the service
systemctl start nodeserver.service
Verify it is running
systemctl status nodeserver.service
● nodeserver.service - Node.js Example Server
Loaded: loaded (/etc/systemd/system/nodeserver.service; enabled)
Active: active (running) since Thu 2015-12-31 09:29:35 NZDT; 7s ago
Main PID: 8952 (node)
CGroup: /system.slice/nodeserver.service
└─8952 /usr/local/bin/node /opt/nodeserver/server.js
Dec 31 09:29:35 fileserver nodejs-example[8952]: Server running at http://0.0.0.0:1337/
Security / testing
Of course this service would run as root, which you probably shouldn’t be doing, so you can edit /etc/systemd/system/nodeserver.service
to run it as a different user depending on your system. If you make any changes to the service file, you will need to do a
systemctl daemon-reload
before reloading the service:
systemctl restart nodeserver.service
I always suggest doing a systemctl status nodeserver.service
after edits and a restart to ensure the service is running as expected.
Now finally we can test how systemd restarts the process if it unexpectedly dies (thanks Mark for the suggestion). We will manually “kill” the running process by finding its Process ID (pid), and note how systemd automatically restart it again:
ps -ef | grep server.js # find the current pid
kill 12345 # kill the process by its pid reported above
ps -ef | grep server.js # notice node process is immediately respawned with a different pid