My web app has 3 main node.js components: website, feeds and jobs.
To start these I am using forever:
//forever.js
var forever = require('forever');
function start(name){
forever.start( ['coffee', name + '.coffee'], { /* log options */ } )
};
start('website');
start('feeds');
start('jobs');
What I first noticed is that if I run script it wont run it as a daemon. ( Which is most likely normal )
node forever.js
So what I did next was run the forever.js script with forever. I am not sure if this is correct, there is also a forever.startDaemon so not sure which one I should use.
forever start forever.js
This works but the problem is that I would like to restart all the processes when a new version of my app is published. I am using git's post-receive hook to run the forever.js the first time but if I do this on each post-recieve it will just spawn 3 processes each time.
So I guess I need a way to restart 3 processes if they are already running. I thought to do this with forever.list but the documentation only say:
forever.list (format, callback)
Returns a list of metadata objects about each process that is being run using
forever. This method is synchronous and will return the list of metadata as such.
Only processes which have invoked forever.startServer() will be available from
forever.list()
First of all I am not sure what format means and second it expects a callback but then it says its synchronous. Which is a little confusing and I am not sure how to use list.
In the end all I want to do is start/restart 3 node.js processes on git's post-receive hook.
I think the best way to do this is:
forever start website.js
forever start feeds.js
forever start jobs.js
and then in your git post-receive hook:
forever restart website.js
forever restart feeds.js
forever restart jobs.js
Wrapping these node processes inside a single process is not a good idea. I now personally use Supervisord with monit instead of forever (supervisord is more stable & powerful than forever IMHO).
I do it like this:
#!/bin/sh
# Make sure we're in the right place
DIR=$(cd $(dirname "$0"); pwd)
cd $DIR
echo "[ I am $USER and I changed PWD to $DIR ]"
forever restart --spinSleepTime=2000 api_daemon.js || (forever start --spinSleepTime=2000 api_daemon.js && forever list)
Works like a charm, I never get duplicate processes using ./run.sh
To read logs, I use
tail -f /path/to/.log
Yes, it's possible. You need to use npm run forever command to run a script.
Add this to your package.json
"scripts": {
"forever" : "forever start api/api-server.js && forever start www/www-server.js && forever start upload/upload-server.js && forever start static/static-server.js",
"test": "echo \"Error: no test specified\" && exit 1"
}
You can create package.json using npm init
Related
I am using forever in npm start to start the node.js app, and I would like to have a npm stop to terminate the task. How can I stop the right task? I really like to not use stop all
Normally you want to assing a uid and then stop the process based on assign name, for example:
1. Starting:
forever start --uid=myapp index.js
2. Stopping only myapp:
forever stop myapp
I am trying to have a nodejs application start automatically on system boot. Basically all I need is to run the command node /dir/app.
I am using openwrt on an Arduino Yun. And have tried a couple things.
On the openwrt website it said I can do this. https://wiki.openwrt.org/inbox/procd-init-scripts :
#!/bin/sh /etc/rc.common
USE_PROCD=1
start_service() {
procd_open_instance
procd_set_param command node ///www/www-blink.js
procd_close_instance
}
I have also tried changing the dir to /www/www-blink.js not ///
However i'm not sure what i'm doing wrong as nothing comes up when I try run it with /etc/init.d/node-app start I am obviously writing the code wrong but i'm not sure what it should exactly look like.
The other thing I have tried is the node modules forever and forever-service.
I downloaded them on my computer using npm install -g forever and forever-service aswell. I transfered them to usr/lib/node_modules on my arduino yun. However when I try to use and forever(-service) commands it says
-ash: forever: not found
I have tried a couple other things, however nothing has worked. Any help would be greatly appreciated.
-- I also need to be able to start my express script with npm start not node app but I guess the first thing is getting it to work at all.
you can put the starting command (node /dir/app &)in the /etc/rc.local script. This will start your nodejs application automatically on system boot.
OpenWRT procd has a "respawn" parameter, which will restart a service that exits or crashes.
# respawn automatically if something died, be careful if you have an
# alternative process supervisor if process dies sooner than respawn_threshold,
# it is considered crashed and after 5 retries the service is stopped
procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
So, you cold just add:
procd_set_param respawn 60 5 5
or something like that to your OpenWRT procd initscript. This 60 5 5 means it will wait 5s between respawns (middle parameter), and if it respanws more than 5 times (last parameter) in 60s (first parameter), it will disable the service ("restart loop" detected).
Refer to this page for more information:
https://openwrt.org/docs/guide-developer/procd-init-scripts
You need to execute your node application like a Linux Service.
Upstart is perfect for this task
Upstart is an event-based replacement for the /sbin/init daemon which handles starting of tasks and services during boot, stopping them during shutdown and supervising them while the system is running.
If you have an app like this (for example):
// app.js
var express = require('express')
var app = express()
var port = process.env.PORT
app.get('/', function(req, res) {
res.send('Hello world!')
})
app.listen(port)
With a package.json like this:
{
"name": "my-awesome-app",
"version": "1.0.0",
"dependencies": {
"express": "^4.13.3"
},
"scripts": {
"start": "node app.js"
}
}
We create a upstart configuration file called myAwesomeApp.conf with the following code:
start on runlevel [2345]
stop on runlevel [!2345]
respawn
respawn limit 10 5
setuid ubuntu
chdir /opt/myAwesomeApp.conf
env PORT=3000
exec npm start
To finish, put your application (app.js and package.json) in the /opt/myAwesomeApp.conf and copy the configuration file myAwesomeApp.conf in /etc/init/
This is all, now you just need to run service myAwesomeApp start to run your node application as a service
I've never used procd before, but it likely needs the full path to node (e.g., /usr/bin/node). You'd need to make the line something like procd_set_param command /usr/bin/node /www/www-blink.js, assuming the file you want to run is /www/www-blink.js. You can locate node by running which node or type -a node.
Right now i am runnign my nodejs application as npm start. i want to run it in background. I found forever package for this but dont know how can i run a application that i usually run as npm start. So how can i run it using forever ?
I follow this SO but getting this error:
ENVIRONMENT=production forever start app.js
warn: --minUptime not set. Defaulting to: 1000ms
warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info: Forever processing file: app.js
apart of this Is there any other better way to run nodejs in background ?
You are doing it right.
The warnings are just reminding you that some essential information is missing, so it assigns the defaults. To be exact, if your script crashes/exits sooner than a second after start, forever will exit as well.
If you would like to get rid of those warnings:
forever start --minUptime 1000 --spinSleepTime 1000 app.js
Furthermore, you can open the package.json file, find the:
"scripts": {
"start": "node app.js"
},
and change it to:
"scripts": {
"start": "forever start --minUptime 1000 --spinSleepTime 1000 app.js",
"stop": "forever stop app.js"
},
Now you can use npm start and it will invoke forever automatically.
In 2022
Use forever npm package ( https://www.npmjs.com/package/forever )
forever start -c "npm <command\>" /path/to/app/dir/
EXAMPLE
./ means current directory
forever start -c "npm start" ./
For Linux
Use terminal and enter in superuser mode, and try these code
$ nohup node <location of of js file> &
$ exit
Note: This '&' is must before you press enter
or for npm command, just goto the location by cd command where your package.json is stored. Then
$ nohup npm start &
$ exit
Note: This '&' is must before you press enter
To stop it
$ top
You can see process id here, then use following code
$ kill -9 <PROCESS_ID>
I have the following command:
/usr/local/bin/forever start -o /home/username/path/out.log -e /home/username/path/err.log /usr/local/bin/nodemon --watch /home/username/scriptpath --exitcrash /home/username/scriptpath/example.js
Which I understand should:
Run Forever as a daemon
Run Nodemon, which will restart the script when a change is seen in /home/username/scriptpath, and will also 'exit' to forever on crashing, allowing forever to restart it all.
However I'm observing Nodemon not restarting upon changes to the files in the watched folder. (Though forever is restarting on crash, when I intentionally cause one.)
Note: Running only "nodemon example.js" works as expected, and restarts on change to file.
What do I need to change to allow Nodemon to re-start the script upon file changes?
My knowledge of linux commands are limited unfortunately, I may well be using the wrong ones.
It will only watch changes in files that are liked to the script you are running by require.
For instance: forever ./script.js ...
var x = require("./test")
Will restart ./script if ./test is changed.
I use forever-service and nodemon.
Here is an example of how I use it to do all you mention.
This example does the following: everytime a json or raml file in the applications dist/assets folder is modified, wait 10 seconds and then restart the node app (server.js script):
forever-service install raml --script server.js -f " -c nodemon" -o " --delay 10 --watch dist/assets -e json,raml --exitcrash" -e "PATH=/usr/local/bin:$PATH"
It will also dump a log file to /var/log/raml.log
I hope that helps!
Previously, I started my production node app via:
NODE_ENV=production forever start index.js
However, per the suggestions in this question, I'd like to start node with --nouse-idle-notification. I also found this article about setting --max-old-space-size, etc. Unfortunately, nobody I ask can seem to figure out how to tell if the flag is actually accepted by node, so I'm not sure how to tell if my forever syntax is correct.
Furthermore, I can't get forever to accept both arguments...
Eg, if I use this
NODE_ENV=production forever start --max-old-space-size=8192 --nouse-idle-notification index.js
I get the "forever usage information", as if I had tried to start forever without passing a .js file to run (eg, just typing "forever"). If I put the flags before the "start" command, it seems to start, but again I'm not sure how to tell if the flags were accepted...
Can someone please help me with the correct syntax?
You need to pass -c parameter:
forever start -c "node --max-old-space-size=8192 --nouse-idle-notification" index.js
If you list the processes, you'll see the flags are honoured.
forever list
Unless you really love forever for some other reason, try mon.
It's super easy to pass flags because you can specify the exact command:
mon "node --max-old-space-size=8192 --nouse-idle-notification --expose-gc server.js" -d
It monitors only a node process. If you want to monitor a group of processes like forever does, install mongroup, its a bash script that manages mon.
This will save you some RAM, specially if you're monitoring a lot of node processes (I think forever launches one additional node process for every process you want to monitor).
quick tip: last time I checked, TJ Holowaychuk's branch of mon was not working well under linux (I guess he only tested on Mac), but this one works and its the one I'm using right now. EDIT: Actually 2 days ago the issue was closed and the main branch should now be working.
You could try:
forever start --max-old-space-size=8192 --nouse-idle-notification -c "NODE_ENV=production node" index.js