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:
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';
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:
Description=PMS gateway service
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
sudo 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.