How can I run grunt as a daemon? - node.js

I am running a packaged nodejs webserver that allows for reading of epub files (Readium-JS), and it is started with the grunt command.
However, if I run this on my VPS the server dies as soon as my terminal connection ends.
How can I run this task as a daemon?
I have looked at options like grunt-forever and grunt-daemon but the way the Gruntfile is written using load-grunt-config is messing with my mind and I can't piece together how to isolate the server code.

Here's the solution I found:
As was suggested above, using pm2
However, when I ran
pm2 start grunt
I got an error saying that the grunt module did not exist, which was weird.
So I ended up writing a script which worked:
-- start.js --
var pm2 = require('pm2');
pm2.connect(function() {
pm2.start({
script : '/usr/local/bin/grunt', // Script to be run
args: '--force',
}, function(err, apps) {
pm2.disconnect();
});
});
After running node start.js from the command line, everything sailed smoothly.

Related

How to start nodejs application automatically on openwrt - Arduino Yun -

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.

node command vs app.listen()

I'm confused. So if I use gulp-develop-server, it's got a app.listen():
gulpfile.js
config.server.path is set to './app,js'
server = require('gulp-develop-server');
gulp.task('default', ['server:start'], function(){
});
gulp.task('server:start', function() {
server.listen({ path: config.server.path});
});
My app.js has this:
var koa = require('koa')();
koa.listen(config.server.port, function(){
console.log('Koa app is listening on port ' + config.server.port);
});
so I'm trying to understand better how node is being started. I see people mention doing it manually like "node app.js". So doesn't koa.listen() automatically do a "node" command to start the koa web server? If I use gulp-develop-server and specify server.listen, isn't that doing 2 server.listen() for node?
Just trying to understand the basics here and can't understand why anyone would manually type in 'node [file with .listen]' manually. I'm not doing that manually and server.listen() obviously uses the 'node' command on my app.js.
Your gulpfile is a Node script. So when you run gulp server:start you're executing a Node application, the gulp command is essentially node plus some extra functionality.
The way gulp-develop-server works is it runs an additional Node application as a child process. server.listen is basically just telling gulp-develop-server what script to run.
The naming is a little confusing, but essentially what's going on is: You have 2 Node applications running on your machine (one that you can see, and one in the background), but only 1 server.

Grunt exec running a node command in background

I'm trying to run grunt with a js script. The script start up a server that should be listening all the time in background. To it I'm using grunt and grunt-exec, and my exec.js is like that
start: {
cmd: function () {
var start = 'node server.js &';
console.info('Starting');
return start;
}
}
When I run grunt exec:start the process finish but the server is not running.
Same command without '&' works but it's not the wanted.
I've tried to move the command to a bash but the result is the same, the server is never started when the character '&' is added, neither in the .sh nor in the grunt-exec command.
Finally I solved it changing the command:
var start = "nohup node server.js";
I.t seems run in background properly.

Node.js just returns "..." in terminal

I'm a front end dev trying to learn and get into Node.js
Having trouble at the first hurdle. I have an app.js file in the root of Mac: "/"
app.js has the following:
console.log('hello world!');
Whenever I run node app.js in the terminal I get the following:
> node app.js
...
It looks like you're running the Node.js REPL first. Don't do that... the Node.js REPL is for running immediate evaluations.
Just try running node app.js from your normal system terminal.

Using Heroku Scheduler with Node.js

There is literally no tutorial about using Heroku Scheduler with Node.js. Assume that I have a function called sayHello() and I would like to run it every 10 mins. How can I use it in controller. In ruby you write rake function_name() however no explanation made for Node. Can I write '/sayHello' or I should do extra configuration?
Create the file <project_root>/bin/say_hello:
#! /app/.heroku/node/bin/node
function sayHello() {
console.log('Hello');
}
sayHello();
process.exit();
Deploy to Heroku and test it with $ heroku run say_hello then add it to the scheduler with task name say_hello.
Explanation
Take say_hello.js as an example of a Node.js script that you would normally run using $ node say_hello.js.
Turn it into a script by
removing the .js ending
inserting the 'shebang' at the top: #! /app/bin/node [1][2]
moving it into the bin directory [3]
[1] Read about the shebang on Wikipedia.
[2] The node executable is installed in app/bin/node on Heroku. You can check it out by logging into bash on Heroku with $ heroku run bash then asking $ which node.
[3] Heroku requires scripts to be placed in the bin directory. See Defining Tasks in the Heroku Dev Center.
I agree that the Heroku documentation for scheduling tasks is not very clear for anything other than Ruby scripts. I managed to work it out after some trial and error.
A better approach is to define your schedule file called for example worker.js with following content:
function sayHello() {
console.log('Hello');
}
sayHello();
and then in the heroku schedule, you just write node worker like you define it in the Procfile and that's all!
Christophe's answer worked for me until I needed to pass a parameter to the script, at which point it failed. The issue is that node should not be specified in the task. Here is how exactly to get it working:
In your Procfile, define a process type for your script. See below for a typical Procfile with a web process and, for running "scheduled_job.js", a second process type imaginatively named "worker".
web: node app.js
worker: node scheduled_job.js
In the Heroku scheduler's Task column, just enter the name of the process type ("worker" in this example) with or without parameters. Don't enter 'node' before it. Heroku shows a dollar sign in front of it, so examples of a valid setup would be $ worker (run without arguments) or $ worker 123 abc (to execute scheduled_job.js with arguments "123" and "abc")
I am confused that nobody tried:
$ heroku run node yourScript.js
So put this in Heroku Scheduler
node yourScript.js
Worked for me.
PS: be sure to import everything your script needs.
Following steps work in my situation.
In the root folder add worker.js file.
In worker.js. Write an simple function, like above.
function sayHello() {
console.log('Hello');
}
sayHello();
Go to heroku Scheduler add-ons. Click 'add new job' and type 'worker' in the field. Then set time interval and click save.
Here are something should notice
After update works setting.If using above example, you can use heroku run node worker.js to check if it work. It should be show 'Hello' in your terminal.
I use express-babel starter for my node.js project.
Thnks so much for the previous answers here.
I found the following worked for me where feed.js is the script to run as a job on Heroku.:
<PROJECT_ROOT>/bin/feed.js
The contents of feed.js start with:
#!/usr/bin/env node
async function mediumFeed() {
await fetch('https://medium.com/feed/stokedinfluence')
And end with:
}
mediumFeed();
And on Heroku the job is defined as node bin/medium_feed.js:
To run the node js script locally feed.js you can use from the root of your project directory node bin/feed.js and to run via heroku you can use heroku run feed.js --app <APP_NAME_NOT_PIPELINE_NAME>. When using heroku command, this will run the job from the server where as running node bin/feed.js will run locally. Run locally to test and verify the code works, once deployed verify it works with the heroku run... command

Resources