Skip to content

Instantly share code, notes, and snippets.

@gAlleb
Forked from joepie91/.md
Last active May 7, 2024 09:20
Show Gist options
  • Save gAlleb/2cc74d7f3ef29f9ed25bca56084ae2c0 to your computer and use it in GitHub Desktop.
Save gAlleb/2cc74d7f3ef29f9ed25bca56084ae2c0 to your computer and use it in GitHub Desktop.
Running a Node.js application using nvm as a systemd service

Read this first!

Hi there! Since this post was originally written, nvm has gained some new tools, and some people have suggested alternative (and potentially better) approaches for modern systems. Make sure to have a look at the comments to this article, before following this guide!


The original article

Trickier than it seems.

1. Set up nvm

Let's assume that you've already created an unprivileged user named myapp. You should never run your Node.js applications as root!

Switch to the myapp user, and do the following:

installs NVM (Node Version Manager)

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

download and install Node.js

nvm install 20

verifies the right Node.js version is in the environment

node -v # should print `v20.12.2`

verifies the right NPM version is in the environment

npm -v # should print `10.5.0`

2. Prepare your application

Your package.json must specify a start script, that describes what to execute for your application. For example:

...
"scripts": {
    "start": "node app.js"
},
...

3. Service file

Save this as /etc/systemd/system/my-application.service:

[Unit]
Description=My Application
#After=docker.service
[Service]
#EnvironmentFile=-/etc/default/my-application
Type=simple
Restart=always
ExecStart=/home/myapp/start.sh
WorkingDirectory=/home/myapp/my-application-directory
LimitNOFILE=4096
IgnoreSIGPIPE=false
KillMode=process
#RestartSec=30
User=myapp

[Install]
WantedBy=multi-user.target

You'll want to change the User, Description and ExecStart/WorkingDirectory paths to reflect your application setup.

4. Startup script

Next, save this as /home/myapp/start.sh (adjusting the username in both the path and the script if necessary):

#!/bin/bash
. /home/myapp/.nvm/nvm.sh
npm start

This script is necessary, because we can't load nvm via the service file directly.

Make sure to make it executable:

chmod +x /home/myapp/start.sh

5. Enable and start your service

Replace my-application with whatever you've named your service file after, running the following as root:

  1. systemctl enable my-application
  2. systemctl start my-application

To verify whether your application started successfully (don't forget to npm install your dependencies!), run:

systemctl status my-application

... which will show you the last few lines of its output, whether it's currently running, and any errors that might have occurred.

Done!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment