×
Community Blog Running Your Node.js Application on ECS with Systemd or Forever

Running Your Node.js Application on ECS with Systemd or Forever

In this article, we will explore various ways to keep our Node.js application running on an ECS server using systemd and forever.

By Dassi Orleando, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud's incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.

Overview

NodeJS became one of the platform by excellence to build web applications and real time system because of its simplicity, speed and especially due to its double-edged sword allowing to build a complete application just with one programming language for both the front and the back end which is Javascript.

Once an application has been built with NodeJs, we quickly feel the need to deploy it to let the word know what we've just did, meaning we'll need a server to host our application. This isn't the most difficult thing even though, but keeping it 100% available can sometimes be a nightmare.

We need our application to be always running no matter what happens as an unexpected crash, an exception, a bug, IO failure or any other reason.

For this article, we've chosen to run/manage our application either with systemd, or with the famous forever tool which will be first detailed in the next lines or even make a merge and do both of them work in sync at the same time. We will be testing both methods on an Alibaba Cloud Elastic Compute Service (ECS) instance.

Prerequisites

  1. Basic knowledge of NodeJS
  2. A server with Unix-like OS, such as Ubuntu

Install NodeJs & NPM

If you haven't yet a server, here is where you can get a fully working ECS with all the required support.

Get the latest NodeJS version on the official website accessible here, just choose the corresponding archive for your operating system then proceed with the installation.

Once done you'll have both NodeJs and NPM installed on your computer, here are some simple commands you can use to assert the installations was a success:

  • node -v
  • npm -v

These will respectively output NodeJS and NPM versions you've just installed, at the time of writing this piece the latest NodeJS version is 10.15.0 and 6.4.1 for NPM.

Note: It's recommended to install these using nvm then it'll be handy to manage versions switching.

Install Forever on Your ECS Server

Let's consider you've NodeJs & NPM installed already on your server, here are the commands to type in order to have forever globally installed also: npm install forever -g.

Note that Systemd comes shipped with all modern Linux/Unix like operating system, it's the system and service manager for Linux responsible to start, stop and restarting programs; since we're using Ubuntu we're good to go.

Write a simple NodeJs Script

We're going to write a basic script that is returning a simple Json response over the 3000 port as follow:

var http = require('http');

http.createServer(function (req, res) {
   var data = {success: true, message: 'Simple NodeJS App'};
   res.writeHead(200, {'Content-Type': 'application/json'});
   res.end(JSON.stringify(data));
}).listen(3000);

Let's do a normal run with the command node script.js, on script.js the file containing our lines of code, here's the result shown by Mozilla Firefox at http://47.254.88.191:3000/

1

47.254.88.191 is our server IP address, must be changed with yours to see your app running.

Start the Script with Forever Tool

Forever is a simple command line tool for ensuring that a given script runs continuously, it's an open source project accessible over on Github.

It also offers an API to use it straight into your program, here you have to install forever-monitor.

To run your forever script, you only need to run the following command: forever start script.js.

Your output will be similar to this:

warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info:    Forever processing file: script.js

Now one of the most used forever commands you'll always keep your eyes on is forever list which will list all scripts launched with forever along with their respective PID and log file location, here's ours:

info:    Forever processes running
data:        uid  command                                    script    forever pid   id logfile                                uptime       
data:    [0] ipYG /path/dassiorleando/.nvm/v10.15.0/bin/node script.js 29942   29954    /Users/dassiorleando/.forever/ipYG.log 0:0:0:31.696

To have the log files for all running scripts we can use this command forever logs, we have this as there is only one script (script.js) actually running:

info:    Logs for running Forever processes
data:        script    logfile                                
data:    [0] script.js /path/dassiorleando/.forever/ipYG.log

Some other useful forever commands:

  • forever start: starts a script as a daemon
  • forever stop: stops the daemon script by Id|Uid|Pid|Index|Script
  • forever stopall: stops all running scripts
  • forever restart: restarts the daemon script
  • forever restartall: restarts all running forever scripts
  • forever cleanlogs: deletes all historical forever log files
  • forever config: lists all forever user configurations
  • forever set : defines a forever config value for an unique key
  • forever clear : clears the specified forever config by its key

The full actions list + some options can be found at https://github.com/foreverjs/forever#readme

If you're interested in a great alternative to forever you must take a look at PM2 which even have a built-in Load Balancer + nice graphics shown in the terminal as output of some commands to have services status/details.

Nodemon is also cool but the purpose of this article isn't to show all of these tools, just keep in mind that the same concept remains among them meaning we should focus on the main context of a NodeJs App that should always be in running state.

Systemd Setup for script.js

To be able to run a script/program using systemd, we first need to create the corresponding systemd unit file called service file.

Let's create that file by typing sudo nano /etc/systemd/system/ourscript.service in our terminal, here ourscript will be our script's name known by systemd.

The .service at the end of the file name is important and not to be neglected unless nothing will work.

Our configuration file content needs to be similar to this (basic working setup):

[Unit]
Description=Our Simple NodeJS Script
Documentation=https://doc.ourscript.com
After=network.target

[Service]
User=ubuntu
ExecStart=node /path/to/our/script.js
Restart=always

[Install]
WantedBy=multi-user.target

Some understanding of the syntax above:

  • Description: it's obvious that it describes our script/program
  • Documentation: a space separated list of URIs containing the documentation for this service, accepted are only URIs in the form: http://, http://, file:, info:, man:
  • After=network.target: instructs systemd to start our script when the computer boots up after the main networking functionality is online
  • User=ubuntu: tells systemd that our App should be run as the ubuntu user, ubuntu here should be a user of your system if not specified any user will be able manage this service
  • ExecStart: instructs how to start our script, it's the command we were using for the normal run with the NodeJs binary (node script.js) but now with the absoluate path for the script location
  • Restart=always: to always restart our script whenever it goes down, is killed or reaches a time-out
  • WantedBy=multi-user.target: means our script will start when the system reach runlevel 2

Here are some other interesting options useful for advanced user as:

  • Environment=NODE_ENV=production: can be used inside the [Service] part to specify an environment variable that will be used into our App, here the NODE_ENV is defined with the value production.
  • ExecStop: the command and argument to run when the script stops
  • ExecReload: the command to be run when the service reloads
  • Group=nodejs: specify the group of the user allowed to launch the service
# Output to syslog
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=our-nodejs-script

The above lines define the standard output for verbose and error messages plus a logging identifier for our script, these should be defined into the [Service] part.

Some Run Levels:

2

Once the configurations are Ok, we can now manage our script (called ourscript into the system) using the following systemctl commands:

  • sudo systemctl start ourscript: to start script.js then be able to access it again at http://47.254.88.191:3000/
  • sudo systemctl restart ourscript: to restart script.js
  • sudo systemctl stop ourscript: to stop script.js
  • sudo systemctl status ourscript: to get script.js status (running or stopped)
  • sudo systemctl enable ourscript: then it'll start up when your server boots
  • sudo systemctl disable ourscript: not allowing it to start again when the server boots

You should not surprise to see somewhere a similar syntax but now with .service at the end like sudo systemctl disable ourscript.service, just note that it's the same as the .service at the end can be removed when running systemctl commands.

Use Systemd or Forever

In the above parts we've seen how both of them should work in a separate way with our NodeJs script, instead of trying to look for the best approach between them we could recommend setting up both to work simultaneously and guarantee your 100% NodeJs App availability because:

  • Benefit of all the forever and systemd commands at the same time
  • When the server restart forever will never start then your application will be down
  • Better log management with forever

Here's how the ExecStart and ExecStop could look for both merged into the same process:

ExecStart=forever start /path/to/our/script.js
ExecStop =forever stop /path/to/our/script.js

Just our [Service] part get updated with the right commands for starting and stopping our service.

You see here that we're no more using the normal running command for NodeJs, as we're using systemd with forever we run the App with a forever command.

Conclusion

In this detailed article, we've seen three methods to run a NodeJS script/app, with one method allowing 100% availability on system start/restart using forever and systemd at the same time.

0 0 0
Share on

Alibaba Clouder

2,605 posts | 747 followers

You may also like

Comments