199

I am using node's forever module to keep my node server running. Forever however terminates when there is a system restart. Is there any way I can automatically start the node server (with forever) when the system restarts?

Oliver Salzburg
  • 21,652
  • 20
  • 93
  • 138
kehers
  • 4,076
  • 3
  • 30
  • 31
  • 1
    Is this server in the cloud? Do you have any boot scripts for it? – Jorge Aranda Nov 14 '12 at 18:46
  • 7
    Checkout [PM2](https://github.com/Unitech/pm2)! It also supports startup script generation (systemd, systemv...) http://pm2.keymetrics.io/docs/usage/startup/ – Unitech Nov 04 '16 at 16:48

16 Answers16

349

I would suggest using crontab. It's easy to use.

How to

  1. To start editing run the following replacing the "testuser" with your desired runtime user for the node process. If you choose a different user other than yourself, you will have to run this with sudo.

    $ crontab -u testuser -e
    
  2. If you have never done this before, it will ask you which editor you wish to edit with. I like vim, but will recommend nano for ease of use.

  3. Once in the editor add the following line:

    @reboot /usr/local/bin/forever start /your/path/to/your/app.js
    
  4. Save the file. You should get some feedback that the cron has been installed.

  5. For further confirmation of the installation of the cron, execute the following (again replacing "testuser" with your target username) to list the currently installed crons:

    $ crontab -u testuser -l 
    

Note that in my opinion, you should always use full paths when executing binaries in cron. Also, if the path to your forever script is not correct, run which forever to get the full path.

Given that forever calls node, you may also want to provide the full path to node:

@reboot /usr/local/bin/forever start -c /usr/local/bin/node /your/path/to/your/app.js

Further Reading

cedricbellet
  • 148
  • 2
  • 12
Julian Lannigan
  • 6,492
  • 3
  • 18
  • 12
  • 1
    Any tips on what to check if this seems not to do anything? – UpTheCreek May 07 '13 at 09:47
  • 2
    This approach is good, but only for those cases when the system gets rebooted. If the server is shutted down and then powered on - this cron job won't execute. – ecdeveloper May 17 '13 at 11:25
  • 6
    What makes you think that? http://en.wikipedia.org/wiki/Cron#Predefined_scheduling_definitions Explains that `@reboot` cron's get run on the cron deamon starting. To add I have never come across a situation that would suggest that my cron's that are set at `@reboot` don't run on system boot. The way you shut it down is irrelevant for this. – Julian Lannigan May 17 '13 at 15:54
  • 1
    @JulianLannigan I love the idea of using crontab over an init script for the simplicity of the solution. Are there any disadvantages (other than having the ability to perhaps restart on the command line) to using your solution over a more traditional init script approach? –  May 28 '13 at 08:03
  • With an init script could you do service myapp stop? It would be handy for pausing the server, and I'm not sure what the best way to do that is. – Stephen Smith Nov 08 '13 at 15:22
  • @Stephen this is not an init script, rather it uses the forever library to manage the daemon. All the cron reboot directive does is start your daemon. After that you can do whatever you want via the forever library. See https://github.com/nodejitsu/forever#using-forever-from-the-command-line – Julian Lannigan Nov 11 '13 at 23:35
  • Adding `@reboot` entries to my crontab didn't work for me; neither did the same entries (minus `@reboot`, of course) in `/etc/rc.local`. **That is**, until I prefaced the entries with `/usr/bin/sudo -u {user}`. Therefore, **I think Step 1 ought to be amended.** I tested this form both with and without invoking `/usr/bin/sudo`; it only works with: `(cd /path/to/; /usr/bin/sudo -u myuser /usr/local/bin/forever start /path/to/app.js)`. – Arthur Nov 12 '13 at 18:41
  • @JulianLannigan I was referencing what Tom said. I think I would rather have an init script since I need an easy way to start/stop/restart via command line in 1 command. – Stephen Smith Nov 13 '13 at 23:36
  • 1
    @Arthur You shouldn't have to run sudo from within the crontab. That is why if you want to run it as a different user than yourself, you specify that in the `-u`. Using that writes/edits the crontab for that specific user and when the daemon is started it will process all user's crontabs as their respective users. – Julian Lannigan Nov 25 '13 at 15:20
  • 1
    @Stephen That's the point of `forever`! Read the docs for you can do all that with "one command". `forever start /your/path/to/your/app.js` `forever stop /your/path/to/your/app.js` `forever restart /your/path/to/your/app.js` https://github.com/nodejitsu/forever#using-forever-from-the-command-line – Julian Lannigan Nov 25 '13 at 15:22
  • I get that, but it would be cool to do "forever stop app-alias" rather than that behemoth of a command. I guess it just comes down to preference. I like to find the most elegant solution I can. – Stephen Smith Dec 10 '13 at 01:19
  • 16
    it appears `/home` is not mounted yet, so this won't work if your code lives in `/home`. – chovy Dec 24 '13 at 05:59
  • This approach does not work for me. When my server reboots, forever does not start. Even if I logged in with the user account remotely via SSH, forever still does not run. I am using CentOS x86 6.5. – Vince Yuan Mar 04 '14 at 09:44
  • 6
    I found that the above failed for me because node is not in the path when cron tries to run forever, even with the -c option. However, it turns out that you can add a PATH= statement directly in the crontab as long as it is above the schedule statements. Once PATH is set the the @reboot statement worked like a dream. – YorkshireKev May 25 '14 at 17:48
  • 2
    Thanks for your comment @chovy, it was very helpful. For those using environment variables from bashrc, mind his comment. Since /home is not mounted it won't work. Set the variables at the crontab command like `@reboot varname=value ...` – lsborg Sep 28 '14 at 15:30
  • for me it started on reboot, I can see servers using command forever list, but they do not work. WHen I manually start save node server - it works, even when it is already started on reboot. – Dariux Nov 21 '14 at 14:16
  • It worked for me but I am a little bit concerned on simple shutdowns and restart. It will work? – Vinicius Feb 27 '15 at 04:45
  • @chovy `home` is definitely mounted but I can't say the same if using `~` – Eat at Joes Mar 07 '15 at 00:08
  • if '/home' doesn't work: where else should an app be installed? So it can be used with the user's credentials? (sorry I'm a ubuntu noob) – Alex May 22 '15 at 00:07
  • 2
    App created by express.js use `bin/www` to start service, and `bin/www` use `#!/usr/bin/env node` syntax to require node.js to process it, unfortunately `/usr/local/bin` not in the boot PATH, so my solution is putting the following line at the top of my crontab file: `PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin` to expand the root users PATH variable, that works for me – Hover Ruan Aug 02 '15 at 04:05
127

You can use forever-service for doing this.

npm install -g forever-service
forever-service install test

This will provision app.js in the current directory as a service via forever. The service will automatically restart every time system is restarted. Also when stopped it will attempt a graceful stop. This script provisions the logrotate script as well.

Github url: https://github.com/zapty/forever-service

NOTE: I am the author of forever-service.

arva
  • 2,384
  • 1
  • 17
  • 14
  • 1
    That is great! How can I pass NODE_ENV with forever-service? – ItalyPaleAle Jan 15 '15 at 18:51
  • 2
    Use -e "PORT=80 ENV=prod FOO=bar" option – arva Feb 13 '15 at 10:24
  • 1
    Thanks, I don't know why, but I couldn't get cron to work and this did the trick. – Ricky Goldman May 16 '15 at 23:32
  • 4
    I don't get how to run forever-service. What is that "test" in "forever-service install test"? My command to start my app forever is: "/usr/local/bin/forever start -c /usr/local/bin/node /home/alex/public/node_modules/http-server/bin/http-server -s -d false". What would I have to write? – Alex May 21 '15 at 23:44
  • 3
    test here is the name of the service. when you run forever-service install test it creates a service called test, to run app.js in that directory to be run as a service. I would suggest reading the help documentation on the gihub page, and add a issue there if you are unable to understand it. – arva May 27 '15 at 12:15
  • 1
    Brilliant little tool. Thank you. Took like 2 seconds to set up, works like a champ. This answer deserves more up-votes for this specific use case. – tpie Jun 07 '15 at 16:11
  • 6
    @Alex - to clarify arva's comment - in the example `forever-service install test`, `test` will be the name of the **service**, but not the name of the actual program / node .js file to run. By default, it assumes the name of the program is `app.js`, but you can override it with the `--script` flag, as follows: `forever-service install test --script main.js`. (Untested, so please correct me if there's any syntax detail wrong.) – Dan Nissenbaum Jun 21 '15 at 22:07
  • 3
    @DanNissenbaum Thanks for answering. I am now using PM2 which works beautifully. Instructions: https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps – Alex Jun 22 '15 at 14:59
  • 1
    @Alex That should be an answer, not a comment. – Ted Bigham Dec 14 '15 at 19:27
  • Best app ever!!! Creates service in few keystrokes, all stdout is written to separate log file in /var/log directory for each service you created(still don't know if stderr is written separately). 100% recommended! – dmikam Mar 10 '16 at 20:26
  • 2
    Windows OS users, beware that it is not supported yet, I just realized when I fire install service command! – Vikas Mar 18 '16 at 09:53
  • 1
    Doesn't work on latest Ubuntu because of missing Upstart – Ludek Vodicka Dec 28 '16 at 16:53
  • windows os is not supported – Prashant Tapase Sep 25 '18 at 11:59
  • forever-service is the best feature forever package must have... but never had. – Rana Tallal Apr 28 '19 at 08:46
34
  1. Install PM2 globally using NPM

    npm install pm2 -g

  2. Start your script with pm2

    pm2 start app.js

  3. generate an active startup script

    pm2 startup

    NOTE: pm2 startup is for startting the PM2 when the system reboots. PM2 once started, restarts all the processes it had been managing before the system went down.

In case you want to disable the automatic startup, simply use pm2 unstartup

If you want the startup script to be executed under another user, just use the -u <username> option and the --hp <user_home>:

fsamuel
  • 471
  • 4
  • 5
  • Please don't post the [same answer](https://stackoverflow.com/a/44337452/4687348) to multiple questions. – FelixSFD Jun 03 '17 at 09:51
  • I really love how pm2 is refined, and comes with an awesome monitoring tool. Hope this is highlighted more for others. @rv7 I'm sure you saw this, but there is a windows solution: https://www.npmjs.com/package/pm2-windows-service. Haven't tried it myself though. – John Lee Jun 21 '19 at 18:28
  • This looks way easier than jiggling with forever and forever-service. – Martin Braun May 29 '21 at 01:55
28

This case is valid for Debian.

Add the following to /etc/rc.local

/usr/bin/sudo -u {{user}} /usr/local/bin/forever start {{app path}}

  • {{user}} replaces your username.
  • {{app path}} replaces your app path. For example, /var/www/test/app.js
J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
NiLL
  • 13,645
  • 14
  • 46
  • 59
  • 2
    This method doesn't deal with graceful shutdowns, though for lots of people this is probably not an issue. – UpTheCreek May 21 '13 at 06:55
  • 6
    BTW - I think you should be editing `/etc/rc.local`, not `/etc/init.d/rc.local` – UpTheCreek May 21 '13 at 06:59
  • Agree with @UpTheCreek that /etc/rc.local is the more appropriate place to add this - see: http://unix.stackexchange.com/a/59945 for a great explanation. – So Over It Jun 07 '13 at 12:45
  • 2
    Also, you may want to specify the 'current working directory' in `app.js` to ensure relative files are loaded correctly - `process.chdir('/your/path/to/your/app');` Node.js ref docs [here](http://nodejs.org/api/process.html#process_process_chdir_directory) – So Over It Jun 07 '13 at 13:22
  • 1
    If you need to set environment variables for your Node.JS script (like $PORT for express), adding the following line to `/etc/rc.local` did the trick for me: `( cd /path/to/project && /usr/bin/sudo -u {{user}} env PORT={{port number}} PATH=$PATH:/usr/local/bin sh -c "forever start app.js" )` – sffc Dec 27 '13 at 11:05
  • Using sudo to change the user outputs this error in the error log of rc.local: sudo: sorry, you must have a tty to run sudo – woj.sierak Jul 05 '15 at 12:33
13

An alternative crontab method inspired by this answer and this blog post.

1. Create a bash script file (change bob to desired user).

vi /home/bob/node_server_init.sh

2. Copy and paste this inside the file you've just created.

#!/bin/sh

export NODE_ENV=production
export PATH=/usr/local/bin:$PATH
forever start /node/server/path/server.js > /dev/null

Make sure to edit the paths above according to your config!

3. Make sure the bash script can be executed.

chmod 700 /home/bob/node_server_init.sh

4. Test the bash script.

sh /home/bob/node_server_init.sh

5. Replace "bob" with the runtime user for node.

crontab -u bob -e

6. Copy and paste (change bob to desired user).

@reboot /bin/sh /home/bob/node_server_init.sh

Save the crontab.

You've made it to the end, your prize is a reboot (to test) :)

Frenchcooc
  • 910
  • 6
  • 20
Emre
  • 831
  • 11
  • 13
  • This method worked best for me. Forever would quit out when I put a full path to the server.js file. If I ran it in the same directory, foreveer would work fine. The reason it failed is the server.js file included other files, but the paths were messed up. Using this method, I could CD in my .sh script to the directory, then run everything relative to there. – BeardedGeek Dec 21 '15 at 15:52
9

Copied answer from the attached question.

You can use PM2, it's a production process manager for Node.js applications with a built-in load balancer.

Install PM2

$ npm install pm2 -g

Start an application

$ pm2 start app.js

If you using express then you can start your app like

pm2 start ./bin/www --name="app"

Listing all running processes:

$ pm2 list

It will list all process. You can then stop / restart your service by using ID or Name of the app with following command.

$ pm2 stop all                  
$ pm2 stop 0                    
$ pm2 restart all               

To display logs

$ pm2 logs ['all'|app_name|app_id]
Community
  • 1
  • 1
Vikash Rajpurohit
  • 1,525
  • 2
  • 13
  • 13
  • How does it start **AUTOMATICALLY** on system boot? You just copy/pasted CLI manual typing – Green Nov 07 '17 at 07:12
  • @Green , Run, ```$pm2 startup``` After that you will see pm2 asking to manually run a command, copy and run that. Then, ```$pm2 save``` Now your app.js will survive system reboots – yajnesh Jan 12 '18 at 10:06
7

You need to create a shell script in the /etc/init.d folder for that. It's sort of complicated if you never have done it but there is plenty of information on the web on init.d scripts.

Here is a sample a script that I created to run a CoffeeScript site with forever:

#!/bin/bash
#
# initd-example      Node init.d 
#
# chkconfig: 345 
# description: Script to start a coffee script application through forever
# processname: forever/coffeescript/node
# pidfile: /var/run/forever-initd-hectorcorrea.pid 
# logfile: /var/run/forever-initd-hectorcorrea.log
#
# Based on a script posted by https://gist.github.com/jinze at https://gist.github.com/3748766
#


# Source function library.
. /lib/lsb/init-functions


pidFile=/var/run/forever-initd-hectorcorrea.pid 
logFile=/var/run/forever-initd-hectorcorrea.log 

sourceDir=/home/hectorlinux/website
coffeeFile=app.coffee
scriptId=$sourceDir/$coffeeFile


start() {
    echo "Starting $scriptId"

    # This is found in the library referenced at the top of the script
    start_daemon

    # Start our CoffeeScript app through forever
    # Notice that we change the PATH because on reboot
    # the PATH does not include the path to node.
    # Launching forever or coffee with a full path
    # does not work unless we set the PATH.
    cd $sourceDir
    PATH=/usr/local/bin:$PATH
    NODE_ENV=production PORT=80 forever start --pidFile $pidFile -l $logFile -a -d --sourceDir $sourceDir/ -c coffee $coffeeFile

    RETVAL=$?
}

restart() {
    echo -n "Restarting $scriptId"
    /usr/local/bin/forever restart $scriptId
    RETVAL=$?
}

stop() {
    echo -n "Shutting down $scriptId"
    /usr/local/bin/forever stop $scriptId
    RETVAL=$?
}

status() {
    echo -n "Status $scriptId"
    /usr/local/bin/forever list
    RETVAL=$?
}


case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        restart
        ;;
    *)
        echo "Usage:  {start|stop|status|restart}"
        exit 1
        ;;
esac
exit $RETVAL

I had to make sure the folder and PATHs were explicitly set or available to the root user since init.d scripts are ran as root.

Hector Correa
  • 26,290
  • 8
  • 57
  • 73
6

Use the PM2

Which is the best option to run the server production server

What are the advantages of running your application this way?

  • PM2 will automatically restart your application if it crashes.

  • PM2 will keep a log of your unhandled exceptions - in this case, in a file at /home/safeuser/.pm2/logs/app-err.log.

  • With one command, PM2 can ensure that any applications it manages restart when the server reboots. Basically, your node application will start as a service.

ref: https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps

Community
  • 1
  • 1
Vishnu Mishra
  • 3,683
  • 2
  • 25
  • 36
5

Forever was not made to get node applications running as services. The right approach is to either create an /etc/inittab entry (old linux systems) or an upstart (newer linux systems).

Here's some documentation on how to set this up as an upstart: https://github.com/cvee/node-upstart

snez
  • 2,400
  • 23
  • 20
  • Upstart failed me on CentOS and I read that it's going to disappear. Creating an init.d entry isn't really the most user friendly way, but it's linux I suppose :) – Jorre Mar 23 '14 at 17:52
5

crontab does not work for me on CentOS x86 6.5. @reboot seems to be not working.

Finally I got this solution:

Edit: /etc/rc.local

sudo vi /etc/rc.local

Add this line to the end of the file. Change USER_NAME and PATH_TO_PROJECT to your own. NODE_ENV=production means the app runs in production mode. You can add more lines if you need to run more than one node.js app.

su - USER_NAME -c "NODE_ENV=production /usr/local/bin/forever start /PATH_TO_PROJECT/app.js"

Don't set NODE_ENV in a separate line, your app will still run in development mode, because forever does not get NODE_ENV.

# WRONG!
su - USER_NAME -c "export NODE_ENV=production"

Save and quit vi (press ESC : w q return). You can try rebooting your server. After your server reboots, your node.js app should run automatically, even if you don't log into any account remotely via ssh.

You'd better set NODE_ENV environment in your shell. NODE_ENV will be set automatically when your account USER_NAME logs in.

echo export NODE_ENV=production >> ~/.bash_profile

So you can run commands like forever stop/start /PATH_TO_PROJECT/app.js via ssh without setting NODE_ENV again.

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
Vince Yuan
  • 10,533
  • 3
  • 32
  • 27
  • got same problem on debian 7.6. This fixed for me. Many thanks. – Daniele Vrut Sep 09 '14 at 10:34
  • Just in case that you don't want to use 'forever', you can change the line to 'su - USER_NAME -c "NODE_ENV=production node /PATH_TO_PROJECT/bin/www"'. – yaobin Oct 03 '15 at 18:43
3

I wrote a script that does exactly this:

https://github.com/chovy/node-startup

I have not tried with forever, but you can customize the command it runs, so it should be straight forward:

/etc/init.d/node-app start
/etc/init.d/node-app restart
/etc/init.d/node-app stop
chovy
  • 72,281
  • 52
  • 227
  • 295
2

The problem with rc.local is that the commands are accessed as root which is different than logging to as a user and using sudo.

I solved this problem by adding a .sh script with the startup commands i want to etc/profile.d. Any .sh file in profile.d will load automatically and any command will be treated as if you used the regular sudo.

The only downside to this is the specified user needs to loggin for things to start which in my situation was always the case.

Moe Elsharif
  • 358
  • 2
  • 10
1

I tried lots of the above answers. None of them worked for me. My app is installed in /home and as user, not as root. This probably means that when the above mentioned start scripts run, /home is not mounted yet, so the app is not started.

Then I found these instructions by Digital Ocean:

https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps

Using PM2 as explained was very simple and works perfectly: My virtual servers had two physical crashes since - downtime was only about a minute.

Alex
  • 2,117
  • 5
  • 28
  • 36
  • PM2 has much more stars (2x) on github, than forever, and it has more features as well. I think most of the answers are obsolete here. – inf3rno Feb 21 '16 at 05:33
0

complete example crontab (located at /etc/crontab) ..

#!/bin/bash

# edit this file with .. crontab -u root -e
# view this file with .. crontab -u root -l

# put your path here if it differs
PATH=/root/bin:/root/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

# * * * * * echo "executes once every minute" > /root/deleteme

@reboot cd /root/bible-api-dbt-server; npm run forever;
@reboot cd /root/database-api-server; npm run forever;
@reboot cd /root/mailer-api-server; npm run forever;
danday74
  • 52,471
  • 49
  • 232
  • 283
0

I have found my own solution by using serve & npm as follows:

  • Install serve package: npm install -g serve
  • Then have the command serve -s /var/www/sitename to execute on reboot.

This is what works for me on my VPS.

kahveci
  • 1,429
  • 9
  • 23
-2

You can use the following command in your shell to start your node forever:

forever app.js //my node script

You need to keep in mind that the server on which your app is running should always be kept on.

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
Gaurav Singh
  • 189
  • 2
  • 7