Note: This is a living document! To get the most recent information (and the example files), look here, on GitHub. To clone the example:
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.
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.
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.
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.
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.
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'.
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
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:
sudo service apache2 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.
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: