Tips - Running a Node.js process on Debian as a Systemd Service

Tips - Running a Node.js process on Debian as a Systemd Service

This guide will teach you how to run your Node processes automatically on Debian (or even Ubuntu). This will mean that your processes can start when your server boots and that they will keep running in case of crashes.
Fran Hogan©

One cool feature about Systemd is that it comes with the ability to restart processes if they fail, in a variety of configurable ways. What this means is that unlike the old init.d method where we need a process manager such as Forever, we can simply write a line of configuration to restart when crashing.

First things first you’ll need to choose a location to keep your application. On most Linux systems this means putting the code somewhere under /var. However, another recent Debian change is the addition of a new /srv directory, intended to keep files served by the OS. For correctness we’ll make use of that directory. Personally I like to create a /srv/www for keeping files served by a webserver (e.g. Nginx), and a separate /srv/node for keeping node services. With that in mind, let’s use the following directory:

/srv/node/pms_api_gateway

Your application, assuming it is a web app, should be written in such a way that it accepts a port number and interface via configuration (even if you think it’s overkill it’s a good habit to get into). These configuration options can be passed in via CLI arguments, but in general it’s better to use environment variables (CLI arguments can be easily inspected). Database connection settings are also good candidates for Environment variables.

Here’s an example of how to access environment variables using Node:

const server = new hapi.Server();
const port = process.env.MY_PORT || 3000;
const host = process.env.MY_HOST || '127.0.0.1';
server.connection({
  port,
  host
});

And if you want to read those same variables (such as for testing), you can precede your commands with the variables like so:

MY_PORT=3000 MY_HOST=localhost node pms_api_gateway/index.js

With your application written in such a way to accept environment variables for configuration, let’s now create a systemd service file:

sudo vi /lib/systemd/system/pms_api_gateway.service
ln -s /lib/systemd/system/pms_api_gateway.service /etc/systemd/system/pms_api_gateway.service

One thing you can do with Systemd is specify other services which need to run first. In the case of a simple web application we want to wait for networking to be available (for more complex applications you way want to wait for services like MySQL to run as well). We also want the simple behavior of restarting the application when it crashes.

Here’s a Systemd service file adhering to this criteria:

[Unit]
Description=PMS gateway service
After=network.target

[Service]
Environment="MY_HOST=0.0.0.0"
Environment="MY_PORT=8080"
Type=simple
ExecStart=/usr/bin/node /srv/node/pms_api_gateway/index.js
Restart=on-failure

[Install]
WantedBy=multi-user.target

Once that file has been created you’ll want to reload the Systemd daemon and then start our new service:

sudo systemctl daemon-reload
sudo systemctl enable pms_api_gateway.service
sudo systemctl start pms_api_gateway.service

Now, check pms_api_gateway.service status

sudo systemctl status pms_api_gateway.service

systemctl status pms_api_gateway.service

There are other subcommands we can run than start, such as restart and stop. Other Debian services can also be controlled in this manner like mysql and nginx.

In a future post I’ll show how I configure Nginx to serve up many different Node and PHP applications.

Share it :