651

Since this post has gotten a lot of attention over the years, I've listed the top solutions per platform at the bottom of this post.


Original post:

I want my node.js server to run in the background, i.e.: when I close my terminal I want my server to keep running. I've googled this and came up with this tutorial, however it doesn't work as intended. So instead of using that daemon script, I thought I just used the output redirection (the 2>&1 >> file part), but this too does not exit - I get a blank line in my terminal, like it's waiting for output/errors.

I've also tried to put the process in the background, but as soon as I close my terminal the process is killed as well.

So how can I leave it running when I shut down my local computer?


Top solutions:

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Peter Kruithof
  • 10,584
  • 6
  • 29
  • 42

30 Answers30

605

Copying my own answer from How do I run a Node.js application as its own process?

2015 answer: nearly every Linux distro comes with systemd, which means forever, monit, PM2, etc are no longer necessary - your OS already handles these tasks.

Make a myapp.service file (replacing 'myapp' with your app's name, obviously):

[Unit]
Description=My app

[Service]
ExecStart=/var/www/myapp/app.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=/var/www/myapp

[Install]
WantedBy=multi-user.target

Note if you're new to Unix: /var/www/myapp/app.js should have #!/usr/bin/env node on the very first line and have the executable mode turned on chmod +x app.js.

Copy your service file into the /etc/systemd/system.

Start it with systemctl start myapp.

Enable it to run on boot with systemctl enable myapp.

See logs with journalctl -u myapp

This is taken from How we deploy node apps on Linux, 2018 edition, which also includes commands to generate an AWS/DigitalOcean/Azure CloudConfig to build Linux/node servers (including the .service file).

Ari Cooper-Davis
  • 3,374
  • 3
  • 26
  • 43
mikemaccana
  • 110,530
  • 99
  • 389
  • 494
  • 7
    Upstart , when available is also a good solution. either way, you should not rely on a nodejs process to keep your nodejs daemon running. This is one task for the OS solely. killall nodejs and forever is gone.... – 131 Jul 26 '15 at 09:26
  • 25
    Note that it's also possible to run systemd services as a user. See for example [this tutorial](https://wiki.archlinux.org/index.php/Systemd/User). You can put your service file in `~/.config/systemd/user`, start it with `systemctl --user start myapp`, enable it with `systemctl --user enable myapp`. – cdauth Dec 29 '15 at 07:26
  • 8
    Thanks for this answer. This is what i want pure and clear – bmavus Jan 10 '16 at 19:35
  • 8
    I've accepted this answer instead of the "forever" answer, since I also think this is the best way to do it. There are similar answers for Mac & Windows, but I'm guessing the majority is looking for a Linux solution. – Peter Kruithof Jan 16 '16 at 11:56
  • 12
    in EC2 AMI path /etc/systemd/system does not exist. Can you point what is the correct path in AWS EC2 Linux AMI? – René Michel Jan 18 '16 at 19:02
  • Just noting that this method didn't work with Ubuntu 3.13. Ubuntu uses Upstart, not systemd/systemctrl – danyim Feb 06 '16 at 05:35
  • 2
    @danyim Yep, Ubuntu's the last major distro not to. 16.04 (the next LTS) uses systemd. – mikemaccana Feb 06 '16 at 21:04
  • Any idea of how to make something similar on a web server ? – PaulNunezM May 22 '16 at 06:17
  • i cant find also the systemd folder in centOS 6.8 – John Christian De Chavez Jul 14 '16 at 06:20
  • 3
    I got a Failed at step GROUP spawning ... No such process error. Failed to start myapp. The file and directory are definitely correct. Any ideas why my service might not want to start? – xxstevenxo Oct 31 '16 at 20:19
  • 1
    @xxstevenxo That sounds like a question rather than a comment! – mikemaccana Nov 01 '16 at 09:17
  • 1
    @mikemaccana you're absolutely correct. I ended up figuring it out anyways. In order to run the app as a node service, I had to include the path to node before the path to my app. All is working wonderfully now. – xxstevenxo Nov 01 '16 at 19:51
  • 1
    @xxstevenxo Sounds like node isn't in $PATH. Use the nodesource packages linked to from nodejs.org, they'll install it properly (and help you update easier) – mikemaccana Nov 02 '16 at 13:09
  • Can't stop the service. systemctl stop myapp not working. How to reload the service by modifying the code? – murad Jan 18 '17 at 10:30
  • @murad Maybe post that as a question somewhere? – mikemaccana Jan 18 '17 at 12:02
  • @mikemaccana What about `monit`? https://www.cyberciti.biz/tips/howto-monitor-and-restart-linux-unix-service.html – josiah Jul 11 '17 at 16:06
  • @mikemaccana The fact that the JS community felt it was necessary to create ForeverJS is an indication of their ignorance that the Linux/Unix community would have already encountered this problem, recognized it as a general need, and written a solid tool to solve it. A tool like `monit` – josiah Jul 11 '17 at 19:13
  • be careful with this; by making it a service, you restrict it's ability to talk to the desktop. This can be annoying when you're writing something like a server that you use to simulate keyboard events in a drawing program. – Dmytro Aug 25 '17 at 22:19
  • I set ExecStart=/usr/local/bin/node /mypath/index.js and designated User and Group (instead of nobody) to make it work. Otherwise it will complain something like 'Failed at step GROUP spawning /usr/bin/node: No such process' – Howard Liu Oct 07 '17 at 07:02
  • 1
    @HowardLiu Yes, if you don't have a group called `nobody` you might want to try `nogroup` - different Linux distros use different conventions. – mikemaccana Oct 09 '17 at 13:39
  • @HowardLiu Also you're missing an interpreter - node should be at the top of 'index.js' – mikemaccana Jan 03 '18 at 13:15
  • 2
    Thanks for this great answer. I was wasting my time searching for "forever" and "pm2". This is just native and simple. – Pronoy999 Aug 17 '18 at 21:47
  • This worked beautifully! Had to find my node executable though (whereis node) and add that to the shebang. – MrG Dec 11 '19 at 09:07
  • 1
    @mrg You can also add the path to the `Environment` section above. `node` normally installs to `/usr/bin` using the Linux distro packages from https://nodejs.org but you might have it in a different spot if it's installed somewhere else. – mikemaccana Dec 11 '19 at 13:21
  • @ApexND you should probably check the user and group exist then, and make them. – mikemaccana Apr 24 '20 at 11:00
  • I've created the most bare minimum package to create a service file: https://www.npmjs.com/package/linux_service_maker Forks welcome at: https://github.com/joshivaibhavs/linuxServiceMaker.js – VaibhavJoshi Jul 30 '20 at 13:47
  • 2
    Don't forget to `chmod +x app.js`. – InxaneNinja Nov 29 '20 at 11:39
  • Good point @InxaneNinja I've added it to the instructions! – mikemaccana Nov 30 '20 at 10:43
  • After a while of fiddling with this I've noticed sometimes the Node versions aren't right. I advise to set ExecStarts as "node app.js" instead of running it directly using the shebang line. – InxaneNinja Dec 05 '20 at 21:51
  • Couldn't get services to work on EC2 recently. Decided to give PM2 a shot. PM2 is an amazing project, incredibly user friendly (specifically for node users), has a wonderful CLI with visuals. With monitoring, restoring on reboot, simple log management, etc. Saved me maybe hours of work and maintenance. This will be my go-to solution going forward. – Jimmie Tyrrell Mar 18 '21 at 18:38
250

UPDATE - As mentioned in one of the answers below, PM2 has some really nice functionality missing from forever. Consider using it.

Original Answer

Use nohup:

nohup node server.js &

EDIT I wanted to add that the accepted answer is really the way to go. I'm using forever on instances that need to stay up. I like to do npm install -g forever so it's in the node path and then just do forever start server.js

Hutch
  • 10,392
  • 1
  • 22
  • 18
NG.
  • 22,560
  • 5
  • 55
  • 61
  • 151
    cool part to know: `nohup` stands for `no hangup` which comes from the old days, where you wanted you keep a process alive when you "hangup" your modem. – jAndy Oct 28 '10 at 19:48
  • 1
    nowadays it's rather the name of signal 1 that processes receive to warn that the user closed the shell (or lost modem connection, of course :P) – lapo Dec 16 '11 at 09:44
  • 7
    It's not the best solution because if the app encounters an uncaught error the node process will exit and not restart. Still, it's a reasonable option for development. – Andy E May 31 '12 at 18:38
  • 1
    How would I add environmental variables to that? eg: PORT=80 node server.js – Pardoner Oct 02 '12 at 18:45
  • 1
    Check out this answer from SO - http://stackoverflow.com/questions/8825460/nohup-verbose-1-perl-script-pl – NG. Oct 03 '12 at 16:05
  • I'll go so far as to say this and the selected answer is the best of both worlds. Use forever in its "in code" version and then use nohup to start. – nick May 13 '15 at 21:44
  • pm2 is buggy. You should fully test PM2 before go production – Yin Nov 02 '15 at 02:48
  • @user3304007 the forever.js solutions will restart the app if it crashes. – Andy E Jan 30 '17 at 15:24
  • I've used pm2 for 2 years. It would stop responding sometimes while running node app in cluster mode. So, I switched back to use `myapp.service` solution mentioned above now. – Linc Jan 21 '22 at 04:28
  • nohup logs everything to an output file, nohup.out which may cause a full disk. – mpp Jul 14 '22 at 12:17
  • This is also a literal joke among sysadmins about how people who don't know how to administer systems run services. – Vector Gorgoth Jul 28 '23 at 19:47
249

You can use Forever, A simple CLI tool for ensuring that a given node script runs continuously (i.e. forever): https://www.npmjs.org/package/forever

AlexV
  • 22,658
  • 18
  • 85
  • 122
muzz
  • 4,324
  • 2
  • 24
  • 14
  • 6
    With latest node I was unable to get it to stop an app via the script name (error) - also - generally misbehaving (was on OS-X) - all built from source, oddly. Left things in a bad state, didn't fill me with confidence. – Michael Neale Apr 12 '11 at 12:32
  • 4
    While nohup does the trick, forever is a better solution as it daemonizes the process. Great tool! – Peter Kruithof Jun 09 '11 at 09:57
  • 5
    Just by the way, a simpler tutorial is available here: [Keep a node.js server up with Forever](http://blog.nodejitsu.com/keep-a-nodejs-server-up-with-forever) – kehers Sep 29 '12 at 02:20
  • 2
    I did use Forever for a while, at the beginning everything seems ok but then disaster happened. Forever could not manage the processes anymore and let them run wild. Still struggling to find a better solution. I will try to use nohup – L N Jan 21 '13 at 12:25
  • Will Forever automatically restart if the server restarts (for example after a power outage)? – Geoffrey Booth Jan 25 '13 at 17:12
  • 5
    Geoffrey- no, you'll need to do `forever start /path/to/yourApp.js` in your server startup script. – mikermcneil Mar 03 '13 at 17:14
  • 1
    Forever doesn't seem to work on node 0.8 +. Use something like [jesus](https://npmjs.org/package/jesus) instead. – Druska Apr 13 '13 at 19:34
  • Forever works fine for me, using node 0.8 and even node 0.10. Maybe you need to update your local version of forever, @Druska – invalidsyntax Apr 17 '13 at 14:22
  • 1
    Does `forever` automatically start your script whenever you reboot? – Melvin Sep 02 '13 at 08:33
  • No matter what I do when I exit the SSH session I cannot access my application. Tried - "nohup server.js &" , "forever start server.js", "nohup supervisor server.js &" everything. But when I exit ssh connection it stops. Any idea? – Bhoomi Jun 26 '14 at 05:42
  • Ironically? only used **forever** for a while. Kept having issues with it. Now use **pm2** instead. Much clearer and so far no issues. – Craicerjack Mar 24 '15 at 11:42
  • **This answer is badly out of date** Every current Linux distro uses .service files, which do not need forever or pm2 or any other external software. – mikemaccana Dec 22 '15 at 16:07
77

This might not be the accepted way, but I do it with screen, especially while in development because I can bring it back up and fool with it if necessary.

screen
node myserver.js
>>CTRL-A then hit D

The screen will detach and survive you logging off. Then you can get it back back doing screen -r. Hit up the screen manual for more details. You can name the screens and whatnot if you like.

Brent
  • 23,354
  • 10
  • 44
  • 49
  • 3
    Also, tmux is nice. Works like screen (CTRL-B is default instead of CTRL-A, but is configurable). Tmux has panels (split screens). – snapfractalpop Mar 21 '12 at 18:17
  • i'm using this since a couple of weeks for a meteor app. `$screen -dr' for detaching and reattaching might be required occasionally. – Vinay Vemula Apr 09 '15 at 07:42
  • For me the easiest way to have the job done. But I agree, not the best solution – Pomme De Terre Feb 12 '18 at 15:11
  • This solution does not persist after a reboot of system – wnasich May 08 '20 at 13:12
  • In as much as it is not the best solution, for development purposes, it is the best, as, it doesn't require additional dependencies/installations. So +1. (Forgotten about screens entirely) :) – Dark Star1 Mar 29 '22 at 11:39
  • This is a literal joke among sysadmins about how people who don't know how to administer systems run services. – Vector Gorgoth Jul 28 '23 at 19:47
72

2016 Update: The node-windows/mac/linux series uses a common API across all operating systems, so it is absolutely a relevant solution. However; node-linux generates systemv init files. As systemd continues to grow in popularity, it is realistically a better option on Linux. PR's welcome if anyone wants to add systemd support to node-linux :-)

Original Thread:

This is a pretty old thread now, but node-windows provides another way to create background services on Windows. It is loosely based on the nssm concept of using an exe wrapper around your node script. However; it uses winsw.exe instead and provides a configurable node wrapper for more granular control over how the process starts/stops on failures. These processes are available like any other service:

enter image description here

The module also bakes in some event logging:

enter image description here

Daemonizing your script is accomplished through code. For example:

var Service = require('node-windows').Service;

// Create a new service object
var svc = new Service({
  name:'Hello World',
  description: 'The nodejs.org example web server.',
  script: 'C:\\path\\to\\my\\node\\script.js'
});

// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on('install',function(){
  svc.start();
});

// Listen for the "start" event and let us know when the
// process has actually started working.
svc.on('start',function(){
  console.log(svc.name+' started!\nVisit http://127.0.0.1:3000 to see it in action.');
});

// Install the script as a service.
svc.install();

The module supports things like capping restarts (so bad scripts don't hose your server) and growing time intervals between restarts.

Since node-windows services run like any other, it is possible to manage/monitor the service with whatever software you already use.

Finally, there are no make dependencies. In other words, a straightforward npm install -g node-windows will work. You don't need Visual Studio, .NET, or node-gyp magic to install this. Also, it's MIT and BSD licensed.

In full disclosure, I'm the author of this module. It was designed to relieve the exact pain the OP experienced, but with tighter integration into the functionality the Operating System already provides. I hope future viewers with this same question find it useful.

Corey
  • 5,133
  • 3
  • 23
  • 24
  • 11
    I've now ported this to [node-mac](https://github.com/coreybutler/node-mac), providing the same functionality on OSX. – Corey May 20 '13 at 20:47
  • 1
    I have come to the point to schedule a couple of Node programs and stand before a decision to choose node-windows, Forever or Kue. I lean towards node-windows but would like to understand why not not to use Forever or Kue when I want to schedule and monitor a dozen of node programs. Some running forever. Need monitoring too. – Christiaan Westerbeek May 22 '14 at 07:15
  • 6
    Node-windows uses the native OS for managing background services, and the native event log for logging. Forever has it's own custom monitoring & logging. I wrote an article on this at https://medium.com/p/2a602ea657a2 It sounds like you need to schedule your scripts, not run them all the time as background services. Projects like Kue and Agenda are designed for this. Node-windows & Forever serve a different purpose. – Corey May 23 '14 at 00:23
  • 1
    @Corey, how do i run the example included in node-mac ?, from terminal, i tried node install.js, but it does not seem to pickup helloworld.js – Edwin O. Aug 12 '16 at 09:40
  • 1
    @Edwin - Might be best to open a new question with more detail about the problem, including the code you are using. – Corey Aug 12 '16 at 16:32
  • sorted, node install.js actually worked, but i needed to view mac log to see the ouputs of heeloworld.js. Great module btw; – Edwin O. Aug 15 '16 at 00:08
58

If you simply want to run the script uninterrupted until it completes you can use nohup as already mentioned in the answers here. However, none of the answers provide a full command that also logs stdin and stdout.

nohup node index.js >> app.log 2>&1 &
  • The >> means append to app.log.
  • 2>&1 makes sure that errors are also send to stdout and added to the app.log.
  • The ending & makes sure your current terminal is disconnected from command so you can continue working.

If you want to run a node server (or something that should start back up when the server restarts) you should use systemd / systemctl.

Hichame Yessou
  • 2,658
  • 2
  • 18
  • 30
Xeoncross
  • 55,620
  • 80
  • 262
  • 364
32

UPDATE: i updated to include the latest from pm2:

for many use cases, using a systemd service is the simplest and most appropriate way to manage a node process. for those that are running numerous node processes or independently-running node microservices in a single environment, pm2 is a more full featured tool.

https://github.com/unitech/pm2

http://pm2.io

  • it has a really useful monitoring feature -> pretty 'gui' for command line monitoring of multiple processes with pm2 monit or process list with pm2 list
  • organized Log management -> pm2 logs
  • other stuff:
    • Behavior configuration
    • Source map support
    • PaaS Compatible
    • Watch & Reload
    • Module System
    • Max memory reload
    • Cluster Mode
    • Hot reload
    • Development workflow
    • Startup Scripts
    • Auto completion
    • Deployment workflow
    • Keymetrics monitoring
    • API
Hutch
  • 10,392
  • 1
  • 22
  • 18
29

Try to run this command if you are using nohup -

nohup npm start 2>/dev/null 1>/dev/null&

You can also use forever to start server

forever start -c "npm start" ./ 

PM2 also supports npm start

pm2 start npm -- start
Himanshu Teotia
  • 2,126
  • 1
  • 27
  • 38
22

If you are running OSX, then the easiest way to produce a true system process is to use launchd to launch it.

Build a plist like this, and put it into the /Library/LaunchDaemons with the name top-level-domain.your-domain.application.plist (you need to be root when placing it):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>top-level-domain.your-domain.application</string>

    <key>WorkingDirectory</key>
    <string>/your/preferred/workingdirectory</string>

    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/node</string>
        <string>your-script-file</string>
    </array>

    <key>RunAtLoad</key>
    <true/>

    <key>KeepAlive</key>
    <true/>

</dict>
</plist>

When done, issue this (as root):

launchctl load /Library/LaunchDaemons/top-level-domain.your-domain.application.plist
launchctl start top-level-domain.your-domain.application

and you are running.

And you will still be running after a restart.

For other options in the plist look at the man page here: https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man5/launchd.plist.5.html

14

I am simply using the daemon npm module:

var daemon = require('daemon');

daemon.daemonize({
    stdout: './log.log'
  , stderr: './log.error.log'
  }
, './node.pid'
, function (err, pid) {
  if (err) {
    console.log('Error starting daemon: \n', err);
    return process.exit(-1);
  }
  console.log('Daemonized successfully with pid: ' + pid);

  // Your Application Code goes here
});

Lately I'm also using mon(1) from TJ Holowaychuk to start and manage simple node apps.

LoG
  • 1,141
  • 9
  • 15
12

I use Supervisor for development. It just works. When ever you make changes to a .js file Supervisor automatically restarts your app with those changes loaded.

Here's a link to its Github page

Install :

sudo npm install supervisor -g

You can easily make it watch other extensions with -e. Another command I use often is -i to ignore certain folders.

You can use nohup and supervisor to make your node app run in the background even after you log out.

sudo nohup supervisor myapp.js &

Donald
  • 3,901
  • 1
  • 20
  • 15
  • 1
    I think in practice supervisor is a better option than most of the daemon modules, particularly used in conjunction with a webhook to checkout updates. – Iain Collins Feb 07 '14 at 19:10
  • I second this one. If you change PHP files, would you restart Apache or Nginx server? Definitely not. Then why bothering to restart the whole Node.js server even just change one line of code? Though this may not be the best solution, at lease with Supervisor you do not need to worry about the restart process (actually the restart still happen). – Zhang Buzz May 14 '17 at 00:39
7

Node.js as a background service in WINDOWS XP

Installation:

  1. Install WGET http://gnuwin32.sourceforge.net/packages/wget.htm via installer executable
  2. Install GIT http://code.google.com/p/msysgit/downloads/list via installer executable
  3. Install NSSM http://nssm.cc/download/?page=download via copying nnsm.exe into %windir%/system32 folder
  4. Create c:\node\helloworld.js

    // http://howtonode.org/hello-node
    var http = require('http');
    var server = http.createServer(function (request, response) {
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.end("Hello World\n");
    });
    server.listen(8000);
    console.log("Server running at http://127.0.0.1:8000/");
    
  5. Open command console and type the following (setx only if Resource Kit is installed)

    C:\node> set path=%PATH%;%CD%
    C:\node> setx path "%PATH%"
    C:\node> set NODE_PATH="C:\Program Files\nodejs\node_modules"
    C:\node> git config --system http.sslcainfo /bin/curl-ca-bundle.crt    
    C:\node> git clone --recursive git://github.com/isaacs/npm.git    
    C:\node> cd npm    
    C:\node\npm> node cli.js install npm -gf   
    C:\node> cd ..    
    C:\node> nssm.exe install node-helloworld "C:\Program Files\nodejs\node.exe" c:\node\helloworld.js    
    C:\node> net start node-helloworld
    
  6. A nifty batch goodie is to create c:\node\ServiceMe.cmd

    @echo off
    nssm.exe install node-%~n1 "C:\Program Files\nodejs\node.exe" %~s1
    net start node-%~n1
    pause
    

Service Management:

  • The services themselves are now accessible via Start-> Run-> services.msc or via Start->Run-> MSCONFIG-> Services (and check 'Hide All Microsoft Services').
  • The script will prefix every node made via the batch script with 'node-'.
  • Likewise they can be found in the registry: "HKLM\SYSTEM\CurrentControlSet\Services\node-xxxx"
Page2PagePro
  • 158
  • 1
  • 4
7

The accepted answer is probably the best production answer, but for a quick hack doing dev work, I found this:

nodejs scriptname.js & didn't work, because nodejs seemed to gobble up the &, and so the thing didn't let me keep using the terminal without scriptname.js dying.

But I put nodejs scriptname.js in a .sh file, and nohup sh startscriptname.sh & worked.

Definitely not a production thing, but it solves the "I need to keep using my terminal and don't want to start 5 different terminals" problem.

ArtHare
  • 1,798
  • 20
  • 22
6

June 2017 Update:
Solution for Linux: (Red hat). Previous comments doesn't work for me. This works for me on Amazon Web Service - Red Hat 7. Hope this works for somebody out there.

A. Create the service file 
sudo vi /etc/systemd/system/myapp.service
[Unit]
Description=Your app
After=network.target

[Service]
ExecStart=/home/ec2-user/meantodos/start.sh
WorkingDirectory=/home/ec2-user/meantodos/

[Install]
WantedBy=multi-user.target

B. Create a shell file
/home/ec2-root/meantodos/start.sh
#!/bin/sh -
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 8080
npm start

then:
chmod +rx /home/ec2-root/meantodos/start.sh
(to make this file executable)

C. Execute the Following

sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl status myapp

(If there are no errors, execute below.  Autorun after server restarted.)
chkconfig myapp -add
Eman Jayme
  • 230
  • 2
  • 8
  • very Interesting, I am just curious about `iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 8080` what it does. Can you give me more details please. I am not sure but I think it redirects traffic from `80` to `8080` which node server listens to, right? – Shakiba Moshiri May 21 '19 at 07:42
5

If you are running nodejs in linux server, I think this is the best way.

Create a service script and copy to /etc/init/nodejs.conf

start service: sudo service nodejs start

stop service: sudo service nodejs stop

Sevice script

description "DManager node.js server - Last Update: 2012-08-06"
author      "Pedro Muniz - pedro.muniz@geeklab.com.br"

env USER="nodejs" #you have to create this user 
env APPNAME="nodejs" #you can change the service name
env WORKDIR="/home/<project-home-dir>" #set your project home folder here
env COMMAND="/usr/bin/node <server name>" #app.js ?

# used to be: start on startup
# until we found some mounts weren't ready yet while booting:
start on started mountall
stop on shutdown

# Automatically Respawn:
respawn
respawn limit 99 5

pre-start script
    sudo -u $USER echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" >> /var/log/$APPNAME.log
end script

script
    # Not sure why $HOME is needed, but we found that it is:
    export HOME="<project-home-dir>"  #set your project home folder here
    export NODE_PATH="<project node_path>"

    #log file, grant permission to nodejs user
    exec start-stop-daemon --start --make-pidfile --pidfile /var/run/$APPNAME.pid --chuid $USER --chdir $WORKDIR --exec $COMMAND >> /var/log/$APPNAME.log 2>&1
end script

post-start script
   # Optionally put a script here that will notifiy you node has (re)started
   # /root/bin/hoptoad.sh "node.js has started!"
end script

pre-stop script
    sudo -u $USER echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/$APPNAME.log
end script
Pedro Muniz
  • 568
  • 12
  • 19
3

use nssm the best solution for windows, just download nssm, open cmd to nssm directory and type

nssm install <service name> <node path> <app.js path> 

eg: nssm install myservice "C:\Program Files\nodejs" "C:\myapp\app.js" 

this will install a new windows service which will be listed at services.msc from there you can start or stop the service, this service will auto start and you can configure to restart if it fails.

Aun Rizvi
  • 449
  • 4
  • 15
3

Since I'm missing this option in the list of provided answers I'd like to add an eligible option as of 2020: docker or any equivalent container platform. In addition to ensuring your application is working in a stable environment there are additional security benefits as well as improved portability.

There is docker support for Windows, macOS and most/major Linux distributions. Installing docker on a supported platform is rather straight-forward and well-documented. Setting up a Node.js application is as simple as putting it in a container and running that container while making sure its being restarted after shutdown.

Create Container Image

Assuming your application is available in /home/me/my-app on that server, create a text file Dockerfile in folder /home/me with content similar to this one:

FROM node:lts-alpine
COPY /my-app/ /app/
RUN cd /app && npm ci
CMD ["/app/server.js"]

It is creating an image for running LTS version of Node.js under Alpine Linux, copying the application's files into the image and runs npm ci to make sure dependencies are matching that runtime context.

Create another file .dockerignore in same folder with content

**/node_modules

This will prevent existing dependencies of your host system from being injected into container as they might not work there. The presented RUN command in Dockerfile is going to fix that.

Create the image using command like this:

docker build -t myapp-as-a-service /home/me

The -t option is selecting the "name" of built container image. This is used on running containers below.

Note: Last parameter is selecting folder containing that Dockerfile instead of the Dockerfile itself. You may pick a different one using option -f.

Start Container

Use this command for starting the container:

docker run -d --restart always -p 80:3000 myapp-as-a-service

This command is assuming your app is listening on port 3000 and you want it to be exposed on port 80 of your host.

This is a very limited example for sure, but it's a good starting point.

Thomas Urban
  • 4,649
  • 26
  • 32
3

Use pm2 module. pm2 nodejs module

2

To round out the various options suggested, here is one more: the daemon command in GNU/Linux, which you can read about here: http://libslack.org/daemon/manpages/daemon.1.html. (apologies if this is already mentioned in one of the comments above).

ravi
  • 3,319
  • 4
  • 19
  • 11
1

PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks. https://github.com/Unitech/pm2

1

I am surprised that nobody has mentioned Guvnor

I have tried forever, pm2, etc. But, when it comes to solid control and web based performance metrics, I have found Guvnor to be by far the best. Plus, it is also fully opensource.

enter image description here

Edit : However, I am not sure if it works on windows. I've only used it on linux.

Josh
  • 13,530
  • 29
  • 114
  • 159
1

has anyone noticed a trivial mistaken of the position of "2>&1" ?

2>&1 >> file

should be

>> file 2>&1
osexp2000
  • 2,910
  • 30
  • 29
1

Check out fugue! Apart from launching many workers, you can demonize your node process too!

http://github.com/pgte/fugue

Shripad Krishna
  • 10,463
  • 4
  • 52
  • 65
1

I use tmux for a multiple window/pane development environment on remote hosts. It's really simple to detach and keep the process running in the background. Have a look at tmux

Karl Pokus
  • 772
  • 1
  • 7
  • 14
1

For people using newer versions of the daemon npm module - you need to pass file descriptors instead of strings:

var fs = require('fs');
var stdoutFd = fs.openSync('output.log', 'a');
var stderrFd = fs.openSync('errors.log', 'a');
require('daemon')({
    stdout: stdoutFd, 
    stderr: stderrFd
});
Viktor Nonov
  • 1,472
  • 1
  • 12
  • 26
1

If you are using pm2, you can use it with autorestart set to false:

$ pm2 ecosystem

This will generate a sample ecosystem.config.js:

module.exports = {
  apps: [
    {
      script: './scripts/companies.js',
      autorestart: false,
    },
    {
      script: './scripts/domains.js',
      autorestart: false,
    },
    {
      script: './scripts/technologies.js',
      autorestart: false,
    },
  ],
}

$ pm2 start ecosystem.config.js

Julien Le Coupanec
  • 7,742
  • 9
  • 53
  • 67
1

I received the following error when using @mikemaccana's accepted answer on a RHEL 8 AWS EC2 instance: (code=exited, status=216/GROUP)

It was due to using the user/group set to: 'nobody'.

Upon googling, it seems that using user/group as 'nobody'/'nogroup' is bad practice for daemons as answered here on the unix stack exchange.

It worked great after I set user/group to my actual user and group.

You can enter whomai and groups to see your available options to fix this.

My service file for a full stack node app with mongodb:

[Unit]
Description=myapp
After=mongod.service

[Service]
ExecStart=/home/myusername/apps/myapp/root/build/server/index.js
Restart=always
RestartSec=30
User=myusername
Group=myusername
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/home/myusername/apps/myapp

[Install]
WantedBy=multi-user.target
0

In case, for local development purpose, you need to start multiple instances of NodeJS app (express, fastify, etc.) then the concurrently might be an option. Here is a setup:

Prerequesites

  • Your NodeJS app (express, fastify, etc.) is placed at /opt/mca/www/mca-backend/app path.
  • Assuming that you are using node v.16 installed via brew install node@16

Setup

  1. Install concurrently: npm install -g concurrently

  2. Create a file ~/Library/LaunchAgents/mca.backend.plist

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Label</key>
        <string>mca.backend</string>
        <key>LimitLoadToSessionType</key>
        <array>
            <string>Aqua</string>
            <string>Background</string>
            <string>LoginWindow</string>
            <string>StandardIO</string>
            <string>System</string>
        </array>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/bin/concurrently</string>
            <string>--names</string>
            <string>dev,prd</string>
            <string>--success</string>
            <string>all</string>
            <string>--kill-others</string>
            <string>--no-color</string>
            <string>MCA_APP_STAGE=dev  node ./server.mjs</string>
            <string>MCA_APP_STAGE=prod node ./server.mjs</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>EnvironmentVariables</key>
        <dict>
            <key>PATH</key>
            <string>/usr/local/opt/node@16/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin</string>
        </dict>
        <key>WorkingDirectory</key>
        <string>/opt/mca/www/mca-backend/app</string>
        <key>StandardErrorPath</key>
        <string>/opt/mca/www/mca-backend/err.log</string>
        <key>StandardOutPath</key>
        <string>/opt/mca/www/mca-backend/out.log</string>
    </dict>
    </plist>
    
  3. Load and run: launchctl bootstrap gui/`id -u` $HOME/Library/LaunchAgents/mca.backend.plist

  4. Get a status: launchctl print gui/`id -u`/mca.backend

  5. Stop: launchctl kill SIGTERM gui/`id -u`/mca.backend

  6. Start/Restart: launchctl kickstart -k -p gui/`id -u`/mca.backend

  7. Unload if not needed anymore: launchctl bootout gui/`id -u`/mca.backend

IMPORTANT: Once you are loaded service with launchctl bootstrap any changes you made in file ~/Library/LaunchAgents/mca.backend.plist won't be in action until you unload the service (by using launchctl bootout) and then load it again (by using launchctl bootstrap).

Troubleshooting

See launchd logs at: /private/var/log/com.apple.xpc.launchd/launchd.log

Vlad
  • 6,402
  • 1
  • 60
  • 74
0

I am bit late. Simple solution is to execute below two commands in terminal as shown below.

nohup node ./server.js &
disown -h %1 

Then close your ssh session and node program continues to run. Tested on Ubuntu 18.

Austin
  • 1,709
  • 20
  • 40
-1

This answer is quite late to the party, but I found that the best solution was to write a shell script that used the both the screen -dmS and nohup commands.

screen -dmS newScreenName nohup node myserver.js >> logfile.log

I also add the >> logfile bit on the end so I can easily save the node console.log() statements.

Why did I use a shell script? Well I also added in an if statement that checked to see if the node myserver.js process was already running.

That way I was able to create a single command line option that both lets me keep the server going and also restart it when I have made changes, which is very helpful for development.