Upstart and init.d priority - node.js

I use foreman to run my node.js applications on the production servers (ubuntu server 12).
Foreman has a great tool to create scripts for upstart.
The problem is that when I reboot a server, my application (managed by foreman) is launched before redis-server and I've to build some tricks in order to wait for a valid connection.
The ideal solution will be to start redis-server earlier, and hen the node application when all is started.
Boot configuration :
redis-server is launched by /etc/init.d/redis-server and is /etc/rc2.d/S20redis-server
my node application is started with /etc/init/stocks-streamer*.conf files
My question is : how would you change the boot order of my node application?
I want to wait for redis-server before my application starts but when I do this, it doesn't start :
start on (started redis-server)
I imagine that it's because no events are sent from init.d scripts to upstart but perhaps there is a way I don't know ?
Thanks by advance for your help !

Perhaps you should have redis be started by foreman instead, so you can better control all the dependencies of your app.
Or make sure foreman start much later than redis (make sure foreman's link in /etc/rc2.d is listed later than S20*.
One more alternative: have redis server also be started by upstart, this is likely going to help upstart manage the dependencies.
There are explanations on how to do this here: https://gist.github.com/bdotdub/714533
And I suggest using "Start must precede another service" instead (http://upstart.ubuntu.com/cookbook/#start-must-precede-another-service) so that redis gets started when you start your own service.

Since this question has no accepted answer, and given I just had the same problem here, I figured I would provide another solution. The question could be re-stated as:
How do I make an upstart job wait on an init.d script?
As the OP says in the question, it's possible to emit an upstart event when the init.d script is started. This way, the upstart job can have a simple start on started SCRIPT_NAME declaration.
In my case, using a custom CentOS-based distribution, my /etc/rc.d/rc is in charge of executing the sysvinit (init.d) scripts. That script is fully upstart aware, and so emits upstart events for each sysvinit script that is started/stopped.
In other words, the /etc/rc.d/rc script has something like this (simplified to leave the juicy stuff):
for i in /etc/rc$runlevel.d/S* ; do
subsys=${i#/etc/rc$runlevel.d/S??}
initctl emit --quiet starting JOB=$subsys
$i start
initctl emit --quiet started JOB=$subsys
done
I imagine you need to take a look at your scripts and add the event emission where you think it's suitable. In my case, the emission was already there.
You can wait for several events in an upstart job. See this question for how to find out what events are available (I haven't found a better documentation to be honest).
In particular the trick to grep -r emit seems very useful.

Related

Automating services with Linux OS starting up and shutting down

I have a script to start and stop my services. My server is based on Linux. How do I automate the process such that when OS is shutdown the stop script runs and when it is starting up, the start script runs?
You should install init script for your program. The standard way is to follow Linux Standards Base section 20 subsections 2-8
The idea is to create a script that will start your application when called with argument start, stop it when called with argument stop, restart it when called with argument restart and make it reload configuration when called with argument reload. This script should be installed in /etc/init.d and linked in various /etc/rd.* directories. The standard describes a comment to put at the beginning of the script and a uitlity to handle the installation.
Please, refer to the documentation; it is to complicated to explain everything in sufficient detail here.
Now that way should be supported by all Linux distribution. But Linux community is currently searching for better init system and there are two new, improved, systems being used:
systemd is what most of the world seems to be going to
upstart is a solution Ubuntu created and sticks to so far
They provide some better options like ability to restart your application when it fails, but your script will then be specific to the chosen system.

Node.js upstart vs forever

I am looking to daemonize my Node.js application. What's the difference between upstart and forever? Also, are there other packages I might want to considering looking at?
As pointed out in the comments, upstart will be used to start the forever script, since upstart has hooks for system events (like shutdown and startup of your server).
The other differences are:
Upstart was developed for Linux, while forever is platform-independent.
Forever is specific to nodejs, and has some pretty cool features with regards to restarting your server after it crashes, and logging.
Forever is sufficient for development environment, while upstart is necessary if you need to have some control over how your server is stopped. For example, on shutdown, the forever process would simply get killed, but, with an upstart script, you can collect logs and notify the admin.
Upstart allows you to add other monitoring tools, like Monit.
Among the available other solutions, you can try daemon, which is equivalent to forever.
I would disagree with #leorex with regards to upstart setup. Check out this blog post for an excellent example.
upstart is a general utility for daemonizing an application. Forever is designed for Node.js. For most purposes, forever is better for Node.js applications as it is simpler, tuned towards node.js and easy to configure. Just try a few tutorials on upstart and you will agree with me.
The main difference in objective is that upstart is designed to start an application on system boot. Forever doesn't have that and instead is focused on keeping a node.js script running despite crashes (most likely unhandled exceptions). You will be wise to combine the two .. i.e. start forever yourscript.js from upstart (on system boot).
That said you will need to look at your platform specific version of upstart equivalent. Upstart was never on windows and is now deprecated for ubuntu / debian : http://www.markshuttleworth.com/archives/1316
In 2017, alternatives could be :
pm2. Robust, strong community, production-grade solution. Can manage non-node scripts as well. My personal choice.
StrongLoop (slc). Node-only. Production-oriented as well, includes build/packaging, deployment to docker, load-balancing and profiling, but is more recent. Looks promising.
Here is a (maybe biased) comparison of both with Forever.

What are the advantages and disadvantages of using the upstart script or forever script in a context of running node.js scripts ??

I am a node.js developer. I use Amazon ec2 to deploy my node.js apps.
I want to have my node.js service running permanently - restarted if it fails for any reason.
I came across 2 tools . Forever and Upstart
Is there any advantages of using one over the other ?
Is there any other tool which is better ?
Upstart is a system service controller, similar to SysV Init and will start/stop/restart essentially any service registered for it, Node.js-based or not, and it will also automatically start services on system start for you. But Upstart is essentially specific to Ubuntu, and Upstart-specific services won't run on other Linux distros.
Upstart has a SysV Init compatibility layer that you could target,instead, to maintain as broad of a compatibility layer as possible.
Forever is a Node.js application that monitors and restarts other Node.js applications as needed, and as defined by its configuration JSON. Lots of options and fine-grained control over your service without the effort that would be needed to duplicate it in a custom SysV Init script. However, Forever isn't a system service, so if the server is restarted, you'll have to manually start your forever scripts again.
Beyond that, if all you need is something that will restart your script if/when it crashes, and you don't care about it starting automatically on system start, all you need is a bash script as simple as:
#!/bin/bash
while true
do
node ./myScript.js
done
Just to correct a misleading statement in the accepted answer...it is not true that upstart is an Ubuntu-only technology. See:
https://serverfault.com/questions/291546/centos-6-and-upstart
http://searchenterpriselinux.techtarget.com/tip/RHEL-6-ditches-System-V-init-for-Upstart-What-Linux-admins-need-to-know
http://en.wikipedia.org/wiki/Upstart#Adoption
With that, I think it is a much more compelling solution.

How can I daemonize node?

Is there a universally accepted means of deamonizing (and of course, later communicating through signals or some abstraction thereon) a node script?
That is, is there a Node equivalent of:
if (fork())
// parent process, die
exit(1);
// we're a daemon
The following is a list of ways to run Node as a background daemon on
different platforms:
nodejs-autorestart manages a Node instance on Linux which uses Upstart (Ubuntu, Debian, and so on).
fugue watches a Node server, restarting it if it crashes.
forever is a small commandline Node script which ensures a script will run "forever".
node-init is a Node script which turns your Node application into a LSB-compliant init script. LSB being a specification of Linux
compatibility.
There is not a built-in way to do this in Node. Take a look at Writing Daemon's in JavaScript with Node.js for one implementation (warning: this is relatively old and Node moves fast--I haven't tested it. :)
Upstart works well for me, though I'm having an issue when I serve over https. Here's the tutorial I used:
http://kevin.vanzonneveld.net/techblog/article/run_nodejs_as_a_service_on_ubuntu_karmic/
You can use node's process object to send/handle signals.
As others have pointed out there really isn't a way to do this in Node directly. You really need to run it using foreverjs. The reason you need to run it using a monitor like forever, is because error thrown by your code will often result in the entire Node process to quit and exit. A monitor will look for this occurring and restart the process immediately.
It is also important to note that while the process is restarting, your server will not respond to request so plan ahead if you expect this to be a problem and make sure that you have a few servers processes running under a load-balancer.

How to set up a node.js development environment/server (Ubuntu 11.04)

I am trying to set up a development environment for node.js. I assumed at first that it requires something similar to the traditional, "localhost" server approach. But I found myself at a loss. I managed to start a node.js hello world app from the terminal. Which doesn't looked like a big deal - having to start an app from the console isn't that hard. But, after some tweaking, I found out that the changes aren't shown in the browser immediately - you need to "node [appName here]" it again to run.
So, my question is:
Is there a software or a tutorial on how to create a more "traditional" development server on your local machine? Along with port listening setup, various configurations, root directories etc (things that are regular in stacks like XAMMP, BitNami or even the prepackaged Ubuntu LAMP). Since I'm new at node.js, I can't really be sure I'm even searching for the right things on google.
Thanks.
Take a look at :
https://github.com/remy/nodemon
it'll allow you to do - nodemon app.js
and the server will restart automatically in case of failure.
To do this I built a relatively small tool in NodeJS that allows me to start/stop/restart a NodeJS child process (which contains the actual server) and see/change configuration option and builds/versions of the application, with admin options available on a different tcp port. It also monitors said child process to automatically respawn it if there was a error (and after x failed attempts stops trying and contacts me).
While I'm prohibited from sharing source code, this requires the (built-in) child_process module, which has a spawn method that returns a child process I guess, which contains a pid (process id) which you can use with the kill method to kill said child process. Instead of killing it you could also work with SIGINT an catch it within your child application to first clean up some stuff and then exit. It's relatively easy to do.
Some nice reading material regarding this.
http://nodejs.org/docs/v0.5.5/api/child_processes.html

Resources