» Run Node.js as a Service on Ubuntu
The core of our new project runs on Node.js. With Node you can write very fast JavaScript programs serverside. It's pretty easy to install Node, code your program, and run it. But how do you make it run nicely in the background like a true server?
Clever chaps will have noticed you can just use the '&' like so:
node ./yourprogram.js &
and send your program to the background. But:
if Node ever prints something and your console is closed, the STDOUT no longer exists and
yourprogram.jswill diewhat if the process crashes, what if your server reboots?
Ok, so we needed something more robust. More like a real daemon, one that's recognized by the Operating System as such.
upstart
Our servers run Ubuntu's latest: Karmic Koala, which packs a pretty decent
version of upstart. Upstart will eventually replace the well-known
/etc/init.d scripts, and will bring some additional features to the table
like: speed, health checking, simplicity, etc.
Writing an upstart script
Turns out, writing your own upstart scripts is way easier than building init.d
files based on the /etc/skeleton file.
Ok so here's how it looks like; You should store the script in
/etc/init/yourprogram.conf, create one for each Node program you write.
description "node.js server" author "kvz - http://kevin.vanzonneveld.net" # 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 script # Not sure why $HOME is needed, but we found that it is: export HOME="/root" exec /usr/local/bin/node /where/yourprogram.js >> /var/log/node.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
Dont forget to chmod u+x your file so it will be executable.
Wow how easy was that? Told you, upstart scripts are childsplay. In fact they're so compact, you may find yourself changing almost every line cause they contain specifics to our environment.
non-root
Node can do a lot of stuff. Or break it if you're not careful. So you may want
to run it as a user with limited privileges. We decided to go conventional and
chose www-data.
We found the easiest way was to prepend the Node executable with a sudo like this:
exec sudo -u www-data /usr/local/bin/node
Don't forget to change your export HOME accordingly.
Restarting your Node.js daemon
This is so ridiculously easy..
start yourprogram stop yourprogram
And yes, Node will already:
- automatically start at boottime
- log to
/var/log/node.js
..that's been defined inside our upstart script.
initctl
But wait, start and stop are just shortcuts. Who's really behind the wheel
here, is initctl. You can play around with the command to see what other
possibilities there are:
initctl help initctl status yourprogram initctl reload yourprogram initctl start yourprogram # yes, this is the same start
etc
More on Node.js
With Node you can write very fast JavaScript programs serverside. We've seen
examples of chat, key-value store, and full blown http servers. Basically
anything is possible as long as you know JavaScript and the concepts of
parallel/evented processing. You don't? Well if you've ever used
setTimeout(), you'll soon get the hang of it ; )
Node.js video presentation by creator Ryan Dahl
Node.js slides that accompany the presentation
About Node on the official website
Node.js is genuinely exciting by Simon Willison
node.js by Debuggable
You probably shouldn't follow me
Like this Article?
| I'd appreciate it if you leave a comment, spread the word, or consider a small donation |
RelatedArticles like this one» HAProxy Logging in Ubuntu Lucid |
tags: nodejs, ubuntu, karmic, upstart, daemon, transloadit, php
category: Programming - Javascript - Node.js
read: 53,280 times
tagcloud
#33. Andy on 27 January 2012
#32. Rindra on 14 December 2011
First i would like to say that this works really great as is. Thanks a lot!
Now I've tried to use the upstart script with a static file server I've created with node.js
When I run it from the terminal: node main.js everything works fine in the browser. The issue occurs when i start my server as a daemon, start app, nothing appears in the browser.
... [more]
I'm starting on node.js and i love the platform, so is this a misconception on my end? I would love to get your input on this.
Thanks again!
#31. claude hussenet on 27 November 2011
Claude Hussenet
#30. Mauvis Ledford on 18 September 2011
With some research I ended up modifying this line to get it working:
from: start on started mountall
... [more] tp: start on (local-filesystems and net-device-up IFACE=eth0)
I guess, the internet wasn't ready when the script was executing.
Cheers,
Mauvis
#29. Herman A. Junge on 12 September 2011
hermanjunge
#28. dale on 07 July 2011
#27. Geoff Wagstaff on 12 May 2011
#26. Aaron Fay on 04 May 2011
Thanks,
Aaron
#25. Kevin on 17 April 2011
@ Joey: Sure : ) I just like how small upstart scripts can be and that it can resuscitate crashed programs.
#24. Joey on 30 March 2011
For anyone (like me) running a server on an older distro release, using Upstart is either not possible, impractical, or overkill when you already have init.d.
And for anyone (again, like me) running a server on a new distro, you're at least as likely to have systemd (which will replace Upstart in the long run) available to you as you are Upstart.
... [more]
I think I'll stick with good ol' init.d (which is available & highly compatible on every distro I've installed) until the distros figure this out ;)
#23. Eran Hammer-Lahav on 17 March 2011
exec /usr/local/bin/node /where/yourprogram.js >>/var/log/node.log 2>&1
instead? The original version does not save exceptions to the log file.
#22. Kevin on 04 March 2011
#21. ipage on 31 December 2010
#20. peter host on 04 December 2010
As a complement for users who like it the init.d way :
https://gist.github.com/715255
#19. Ovidiu on 28 October 2010
#18. Kevin on 11 October 2010
what happens when you just run
/usr/local/bin/node /where/yourprogram.js 2>&1 >> /var/log/node.log
... [more] what about:
/usr/local/bin/node /where/yourprogram.js ?
#17. watch hellcats online on 01 October 2010
#16. Sami Samhuri on 16 August 2010
#15. Kevin on 12 August 2010
@ Xavier: The same way that I:
export HOME="/root"
... [more] You could export your PATH as well if that's required.
so first echo $PATH, and put that in there
#14. Xavier on 15 July 2010
I checked the require.paths array and it is exactly the same whether I run directly node app.js or if I do "start node".
I also tried to to run "env" before (sudo -u myuser env /usr/local/bin/node /path/app.js ...) but doesn't help.
... [more] I run out of ideas. Thanks for your support.
#13. AFire on 13 July 2010
#12. Kevin on 10 June 2010
#11. Francisco on 25 May 2010
I copy-pasted the example, only replacing /where/yourprogram.js for my program - but after "sudo start myprogram" it must crash. Nothing is logged. Using upstart 0.6.3-11 on karmic.
#10. Francisco on 25 May 2010
Hey guys did you manage to run a real-world program? Mine requires a library with a relative path so I can't call it from anywhere (like, node /path/to/my.js).
I either need to cd /path/to && node my.js , or use chdir - but none has worked for me. Any ideas?
#9. Kevin on 26 February 2010
#8. George on 25 February 2010
The only thing I had to change was that I change to the directory containing my .js file before launching node. For whatever reason, I otherwise have trouble loading static files into my node.js app.
Cheers!
#7. Kevin on 07 January 2010
#6. jz on 25 December 2009
for some reason, on 8.10 i had to put the conf file in /etc/event.d for initctl to find it...
#5. sveisvei on 16 December 2009
#4. Kevin on 15 December 2009
#3. Mariano Iglesias on 15 December 2009
$ nohup script &
#2. Kevin on 15 December 2009
#1. Felix Geisendörfer on 15 December 2009
If you just need something slightly better than "node ./yourprogram.js &", because you might just be doing a long running job, you can type in "screen" and then execute "node ./yourprogram.js" in the new terminal that opens. Screen sessions don't die if you log out, and you can even re-attach them using "screen -r" when you login the next time.