SystemD with NodeJS

Posted on Sunday, July 9, 2017



I want to run a nodeJS application via SystemD.   These will be my simple notes on how to do this.








Simple Node Express app


First let me create a simple Node Express Server.


  > mkdir node-systemd
  > cd node-systemd




  > vi package.json


And put the following in it.


{
  "name": "node-systemd",
  "version": "0.1.0",
  "description": "Simple Node Express app to run via systemd",
  "main": "app.js",
  "private": true,
  "author": "Patrick Bailey",
  "dependencies": {
    "express": "^4.15.2"
  }
}




Now create the app.js


  > vi app.js



var express = require('express');


const app = express()

app.get('/', function (req, res) {
  res.send('Hello World!')
  console.log("Hello World")
})

app.get('/kill', function (req, res) {
  res.send('killing app!')
  console.log("Shutting down application")
  process.exit()
})

app.listen(3000, function () {
  console.log('Example app listening on port 3000!')
})





Now run npm



  > npm install
  > nodejs app.js


Now run a simple curl


  > curl localhost:3000




Now curl the /kill url



  > curl localhost:3000





That should kill the app



And it did.


I wanted to add this so that I can easily test that systemd will restart the app if it is shut down.







SystemD


Let me move my node-system app to /opt on my server


  > sudo mv node-systemd /opt


Then create a nodejs user/group to use to run the nodejs app.   (It will not have a default shell)


  > sudo addgroup nodejs
  > sudo adduser --system --ingroup nodejs \
     --no-create-home nodejs


 


Now change ownership of all the node-systemd files to nodejs:nodejs


  > sudo chown -R nodejs:nodejs /opt/node-systemd





Now create a systemd script


  > sudo vi /lib/systemd/system/nodejs.service


And place the following in it


[Unit]
Description=NodeJS Express Server
Requires=network.target
After=network.target
ConditionPathExists=/opt/node-systemd/app.js

[Service]
Type=simple
PIDFile=/var/run/nodejs.pid
User=nodejs
Group=nodejs
WorkingDirectory=/ opt/node-systemd
ExecStart=/usr/bin/nodejs app.js
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
Alias=nodejs.service




 





Make enable it and start it.  (Enable will cause it to start whenever the server reboots)


  > sudo systemctl enable nodejs.service
  > sudo systemctl start nodejs




Now try and curl it


  > curl localhost:3000




OK that failed I did something wrong…



Query the status of this service


  > sudo systemctl status nodejs




Yep something is wrong.



Running it by hand works…

Switching to the nodejs user and running it works.


  > sudo su nodejs -s /bin/bash





Oops I see it now.  There is a space after / and before opt in my Working Directory.




Let me fix that


  > sudo vi /lib/systemd/system/nodejs.service


And place the following in it


[Unit]
Description=NodeJS Express Server
Requires=network.target
After=network.target
ConditionPathExists=/opt/node-systemd/app.js

[Service]
Type=simple
PIDFile=/var/run/nodejs.pid
User=nodejs
Group=nodejs
WorkingDirectory=/opt/node-systemd
ExecStart=/usr/bin/nodejs app.js
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
Alias=nodejs.service




Now let me start it and check the status

But first I need to reload since the script was altered


  > sudo systemctl daemon-reload




  > sudo systemctl start nodejs
  > sudo systemctl status nodejs


 


Looks better!  Now to test it.



  > curl localhost:3000




That worked.

This program is not currently logging to any directory.  But I can use the journalctl like I might use the tail command to see its output.


  > sudo journalctl -f -u nodejs


Now if I run a few curls





Now let me use the /kill url to kill it and it should restart itself.



  > curl localhost:3000/kill








Boom!   it restarted itself after a failure!


Now to double check it all let me reboot the server and make sure it starts up.


  > sudo reboot now






  > sudo journalctl -f -u nodejs



And start a few curls


  > curl localhost:3000
  > curl localhost:3000
  > curl localhost:3000/kill





Looks good!







References


NA



No comments:

Post a Comment