nearly every Linux distribution comes with systemd, which means forever, monit, PM2, etc. are no longer necessary - your OS already handles these tasks. - Mikemaccana, stackoverflow answer
In couple years, ton of tutorial explain that we should use library like forever, monit, pm2, etc to run nodejs in linux. This happen because nodejs user using nodejs in terminal on development phase, but on production is different scenario, we should run it in background process instead on open terminal.
Today I learn that we do not need other library or other service to run nodejs in background, systemd already solve that problem!. The best part is it include logging report, the journalctl. There is several method run application or service on background in unix system.
Background process is a computer process that runs behind the scenes. Wikipedia
Unix-like system (Linux, ubuntu, debian, Mac OS) can be launched a process in background in many way
Method 1: The &
operator
This operator will run in background but it suspended job (sending SIGCONT
)
Method 2: Nohup
Nohup is a UNIX command which menas “no hang up”. The idea is run single command in background
$ nohup npm run dev &
But you have to search the PID number to stop it!, it’s not practical and hard to use.
Method 3: Systemd
Systemd is a system and service manager that run and start the rest of the system.
$ sudo systemctl start nginx.service
$ sudo systemctl stop nginx.service
$ sudo systemctl restart nginx.service
$ sudo systemctl status nginx.service
It’s easy to use because those have intuitive command that we can use, also systemd have many usefull configuration. We will talk about this.
Setup Nodejs and Project Structure
First of all, you should store your code into server. Usually I have this structure of folder. This is my personal recommendation based my experience in deployment nodejs application
- /app
- /code -- This is the code of project it self
- start.sh -- this is will be our starting point of a service
- your-app-name.service -- service systemd configuration
this structure make our app in single folder along their command and service.
code
folder is your app folder, prepare your application in here, like npm install
, npm run build
, etc. Do your stuff here.
your-app-name.service
is a systemd configuration service that will tell systemd what should he do. Systemd require ExecStart
as starting point of application. We will use start.sh
as our starting point, we can prepare our app in start.sh
file.
start.sh
is the entry point for your service. We can put many of script like npm
, yarn
or nvm
in here.
Execution Script
We will use start.sh
as execution script, just copy these line into file start.sh
. This file store command npm run
to tell service to run that.
#!/bin/bash
npm run start
Add execution permission to this file by running:
$ chmod +x start.sh
NVM use case
In other case we use nvm to switch nodejs version, putting nvm to start.sh
is a bit tricky, we should include nvm.sh
before running the nvm
script.
#!/bin/bash
source /root/.nvm/nvm.sh
nvm use 22
npm run start
If you don’t know where your
nvm.sh
is located, please refer to nvm documentation.
Configure Systemd Service
Edit file your-app-name.service
and fill this configuration
[Unit]
Description=Nodejs app
After=network.target
[Service]
WorkingDirectory=/root/app/code
ExecStart=/bin/bash /root/app/code/start.sh
EnvironmentFile=/root/app/code/.env
Restart=always
User=root
[Install]
WantedBy=default.target
This configuration tell systemd to run command ExecStart
that using env from file EnvironmentFile
and all process run as User root
, this process will start After
network.target
running which is we need that.
This configuration is modified from stackoverflow answer to meet my requirement and workflow. Make sure all folder configuration is match with your server condition.
Install the service
Link file your-app-name.service
to /usr/lib/systemd/system/
$ ln -s /root/app/your-app-name.service /usr/lib/systemd/system/
This will make shortcut (or link) to folder systemd
. Why we do this? because you don’t have to edit the systemd
folder directly, instead update your service from your app folder. This makes our workflow easy and file service close to source code.
Reload Daemon
Reload systemd daemon because we modify the configuration of daemon service
$ sudo systemctl daemon-reload
Enable our service using this command
$ sudo systemctl enable your-app-name.service
After that, manage your service using these commands
# Start service for the first time
$ sudo systemctl start your-app-name.service
# Stop service
$ sudo systemctl stop your-app-name.service
# Restart service
$ sudo systemctl restart your-app-name.service
# show status of service
$ sudo systemctl status your-app-name.service
Debug and Logging
After successfully run our service in background, debug and read log is the important part to make sure our app run smoothly as we expected. We will use journalctl
$ journalctl -u your-app-name -xe
-u
to filter by ourunit
name of service.-x
Augment lgo lines with explanation texts-xe
thee
immediately jump to the end of log (aka. journal)
Read more explanation about journalctl at journalctl manual pages.
Here is some common usefull script journalctl
# use `f` to follow the log in live time
$ journalctl -u your-app-name -xef
# use `n` to show last number of line (in this example is last 100 lines)
$ journalctl -u your-app-name -xe -n 100
Debugging is important in development and production server, journalctl have a lot feature to view log and find log in simple way.
Conclusion
Running Nodejs in background is easy using systemd
, which is have been include some important feature like start
, stop
, logging
. So, you don’t need other library to run nodejs in background, this method can be applied in other type of application which makes it easy to deploy application. I hope this articel can help you all, please share and give me feedback!. Thank you!.