Note: This is a living document! To get the most recent information (and the example files), look here, on GitHub. To clone the example:

git clone git://github.com/Miserlou/NodeDeploy.git

Intro

I've recently learned how to program Node.js applications. I couldn't find tutorial on how to deploy it in the way I wanted to, so I figured out a solution and this is what I've learned.

Node is a really refreshing way to program, and it's turned me from a JavaScript hater into a fan and developer. Everything is event driven, it's highly scalable, and, with Socket.IO, you can make very cool, interactive and collaborative applications. It's also quick, it has a great package manager, and there is a healthy and young community.

The biggest problem I've encountered so far is that because it's so young and development is so active, there isn't very much documentation about how to deploy it yet, so this guide will help you with what I've learned so far. I'm not saying that this guide is completely correct, just that it has worked for me so far. Your milage may very - if you learn anything more, or find that I'm doing something stupid, please post it in the comments or submit a pull request here, on GitHub.

Getting Started

Deploying Node applications is kind of tricky because your app is the webserver. I'm used to deploying Django applications which sit behind the actual webserver, so this was slightly counter-intuitive for me. Also, because your application is the webserver, if it crashes, your whole service is boned. So, we also need a solution to that, too.

Goals

Run a Node-based front end proxy which proxies to, depending on the hostname, either our Node app or a normal (Apache/Nginx) webserver server another application.

It must support WebSockets served from SocketIO.

If the node app crashes (which it will), it must restart.

Servers must start upon the boot of the machine.

It must be secured with SSL.

Proxing

Because we'll be running two different services on the same machine, we will need a proxy to direct the traffic properly. To do this, we will used a Node-based HTTP proxy. If we used a normal proxy, we would lose some of the benefits of the Node server.

To do this, we're going to use the node-http-proxy. We are choosing this over the similar package 'bouncy' because it is slightly faster and there are more examples dealing with SSL, although the API is slightly worse. It's also made by Nodejitsu, who seem knowledgable and responsive.

Proxy As A Service

Because we're in Node land now, we'll actually be writing the proxy server ourselves. I've modified one of the http-proxy examples for our purposes. You can find it here. Just copy it into your /var/www/ folder (or wherever your want it to live). If you want to use it with certificates, modify the file to include the path to your certs.

We'll also want to run this as a service. So, make a new '/etc/init.d/http-proxy' file and put this in it:

and modify it to reflect the path of your application. Your app will also need a 'logs' and a 'pids' folder in it.

We'll also need to do the same for our application itself. Let's make a '/etc/init.d/nodeapp' too.

Again, you'll need to modify this file to reflect the paths to your application.

Application Monitoring

To keep an eye on our application, we'll use an app called 'Monit' to restart it if it goes down. This is available in the Ubuntu package manager, so you can just install it by doing the ol' sudo apt-get install monit. Monit takes an 'rc' file in /etc/monit/monitrc. Again, you'll need to modify this for your own purposes:

To get monit started, you'll also need to change /etc/default/monit so that it contains the line 'startup=1'.

Security

Note: this part needs attention. I really don't think this is the best way of doing this.

As we don't want to run our node proxy as root, we can use an IPTables rule which will send all of the port 80 traffic over to our proxy. To do so, enter this into your terminal:

iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8000

Putting it all together

For this to work, you'll need to have your non-node application on port 9000 (for Apache, this will be in /etc/apache2/ports.conf and in your sites-available file for your site), and you'll need your node application to listen on 8080. You'll also need to set up DNS 'A' records for the different hostnames you'll be using for your servers.

Once you've got that done, as your deploy user, just:

/etc/init.d/nodeapp start

sudo service apache2 start

/etc/init.d/http-proxy start

sudo service monit start

And you're live! It should work with Socket.io, and if you add an IP tables rule for port 443, it should work for SSL too.

Conclusion

Again, this is a living document, and it is not meant to be canonical. It worked for me (January 2012), though it's only a personal deployment, I haven't tested it at "web-scale" (or whatever the kids are calling it these days). To get the example files here, you can clone it from GitHub:

git clone git://github.com/Miserlou/NodeDeploy.git

Best Sites to Find Clients as a Freelance Developer

Fill your pipeline with best-fit clients for your rate, engagement length, and role preferences.

See More Posts About: