Running "npm start" App As a Systemd Service
If you have a npm app that is launched with “npm start” and want to run it as a systemd service in the background without a user, this is how.
Please keep in mind this is really a tutorial how I personally set this up to run Stickybot. I have no idea what I'm doing with systemd so this setup might not be ideal or secure. But it does work.
Example of full stickybot.service will be at the end of this article.
This is also on a Debian based system, I have no idea how Arch or Fedora would do this. I know it works on Ubuntu Server 20.04 and Debian 11
Update August 2024: This guide has since been confirmed to work on AlmaLinux9. Guide is identical, just replace “APT” with “DNF” for installing system packages.
Using a Service File
- Create a text file called myapp.service (in this case stickybot.service) with following content
[Unit] Description=appname [Service] ExecStart=/path/to/main.js Restart=always User=nobody # Note Debian/Ubuntu uses 'nogroup', RHEL/Fedora uses 'nobody' Group=nogroup Environment=PATH=/usr/bin:/usr/local/bin Environment=NODE_ENV=production WorkingDirectory=/path/to/ [Install] WantedBy=multi-user.target
- Copy this file to /etc/systemd/system
sudo cp myapp.service /etc/systemd/system
- Edit your main.js to include to contain
#!/usr/bin/env node
on the very first line
- (Optional but recommended) Convert this file to Unix format. This should prevent incompatibles from different carriage return behaviors between Windows and Linux
- Install dos2unix
sudo apt install dos2unix
- Convert the file
sudo dos2unix /path/to/main.js
- Start your app
sudo systemctl start myapp.service
- See status of your app
sudo systemctl status myapp.service
Stickybot example
cat /etc/systemd/system/stickybot.service
[Unit] Description=Stickybot [Service] ExecStart=/etc/stickybot/src/main.js Restart=always User=nobody # Note Debian/Ubuntu uses 'nogroup', RHEL/Fedora uses 'nobody' Group=nogroup Environment=PATH=/usr/bin:/usr/local/bin Environment=NODE_ENV=production WorkingDirectory=/etc/stickybot/ [Install] WantedBy=multi-user.target
Head of main.js
#!/usr/bin/env node require('dotenv').config(); const Discord = require('discord.js'); const {Client} = Discord; const client = new Client(); const fs = require('fs');
— dustojnikhummer 2022/12/31 22:10