[logo] a small computer

How to Restart a Node.js App Programmatically.

how to restart a node.js app programmatically.

Bradley Kingsley
Published a year ago.
3 minute read
logo of undefined

NodeJS is a pretty nifty programming language. It's easy to pick up and even easier to adopt external libraries to help out with your project. For our use case, we're going to use express for our server and a few others along the way. If it can be done with a library, it can also be done without one (it just needs a little bit more elbow grease) so we'll explore how to restart your Node app from within itself using vanilla Javascript.

The other two methods for restarting your node server programmatically are using pm2 and using forever

Using Forever

Assuming you already have an express server running, the only extra dependency you need is forever.. It's a CLI app useful for running your app in the background, or... forever.

First, install forever.

npm install forever

// or 

yarn install forever

And change your package.json to:

{
	...
	"start": "forever start index.js"
}

Next, let's create a route that allows us to restart the server via an API call. For the sake of brevity, authorization code for our system route has been left out.

const express = require('express');
const app = express();

app.get("/system/reboot", (req, res)=> {
	process.exit(1)
})

When process.exit(1) is called from within the node process, forever detects it and immediately attempts to reboot your app.

Using PM2

PM2 is a process manager like Forever. It comes with a lot of the same features packed in, including automatic reload to prevent downtime and eliminate the need for a lot of common admin tasks.

To use it, repeat the same process as with Forever, replacing forever with pm2 where necessary.

Restarting a NodeJS app from within itself without dependencies

If you're not a big fan of including new libraries into your project or already have one running and just want to add a new route to take care of rebooting your app, the no-dependency way is likely what you need.

To give credit where it's due, here's the Stackoverflow post this code was borrowed from.

...
app.get("/system/reboot", (req, res)=>{
    setTimeout(function () {
        // When NodeJS exits
        process.on("exit", function () {

            require("child_process").spawn(process.argv.shift(), process.argv, {
                cwd: process.cwd(),
                detached : true,
                stdio: "inherit"
            });
        });
        process.exit();
    }, 1000);
})

Here is a breakdown of the code above:

  • Whenever Node exits, it emits an 'exit' event. We listen to this event using process.on('exit')
  • In the callback function, we resolve the child_process module, which uses the spawn method to launch a command in a new process.

    If you're not familiar with how it works, the child_process module lets us access OS functionalities by running any bash command. The child_process.spawn method has the following signature child_process.spawn(command[, args][, options]).

    • process.argv returns an array that contains the command line arguments passed to Node.js when the process is launched.
    • The command to start our app is npm start, which calls node index.js internally. process.argv.shift() gets rid of the first argument in the arguments array ([/path/to/node, index.js]) and returns it.
    • The first element in the arguments array is always process.execPath which returns the absolute path to node. In my case, it's '/home/brad/.nvm/versions/node/v12.16.3/bin/node'.
    • Since we already removed the first element from the array before, the absolute path to our file (which is usually the second argument) is now the only element in our array.
    • Lastly, in the options object, we defined the following properties:
    • cwd: the current working directory of the child process
    • detached: whether or not the child runs independently of the parent process.
    • stdio: configures pipes established between parent and child. inherit passes lets the corresponding stdio stream directly to/from the parent process
    • Finally, we call process.exit(). When this happens, a new process is opened thanks to the above commands.

You can read more about child_process here and all about process here.

Copyright © 2020 The Kenyan Dev