Posted on June 18, 2014 by Chris Harrington

Setting up a Node web server on an Amazon EC2 instance

Up until recently, I’d been hosting Leaf on Heroku. I had a pretty good experience with Heroku and would recommend it to anyone whole heartedly, especially if you’re just getting into the Node space and want to play around a little. It has a free sandbox plan, it’s really easy to get started. That said, however, when you’re getting a little more serious, the cost of Heroku’s offering is almost twice as much as what Amazon offers. Prices today sit at $34.50 for two “drones”, which are the equivalent of two EC2 instances, while the EC2 instances themselves can be purchased for as little as $9 a month (or $18 for two instances). On top of the price difference, EC2 instances have the benefit of being almost 100% configurable, so I can poke around and do however I please.

From here on out, I’ll assume the reader is familiar with Amazon Web Services and have already spun up an EC2 instance with SSH capabilities. I’m using an Amazon Linux instance, but any of the *nix based instances will do the trick.

TODO

Here’s the main list of things that we need to do to get a Node web server up and running. I’m going to be using Leaf as the example here because that’s what I did for my own EC2 instance. Leaf is hosted on GitHub, so we’ll need Git installed as well to pull down the source.

1) Install Git and pull down the code.
2) Install Node and NPM.
3) Build your application.
4) Redirect traffic to/from the appropriate ports.
5) Set up your web server to run until you say otherwise.
6) Celebrate with champagne.

Git

Unsurprisingly, the first step is to install Git.

sudo yum install git

Also unsurprisingly, the second step is to clone your Git repo.

git clone https://github.com/chrisharrington/Leaf.git
cd Leaf

And done. So far so good.

Node

This step is a little trickier, but still a piece of cake. Node and NPM aren’t available in the default repositories that yum knows about on a standard Amazon Linux instance, so we need to add a new repository. The repository we’ll be using is the Fedora Extra Packages for Enterprise Linux (EPEL) repository.

sudo rpm --import https://fedoraproject.org/static/0608B895.txt
sudo rpm -Uvh http://download-i2.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

Once that’s done, we can go ahead and install Node and NPM almost as usual. We just need to specify the newly added repository.

sudo yum install nodejs npm --enablerepo=epel

Build the application

In my case, there’s no building to do; it’s just a quick install of saved packages.

npm install

This step isn’t required, but now would be a good time to make sure that everything looks ok by running your copious amounts of unit tests.

npm test

Redirect traffic

Normally, Leaf runs on port 80, but Amazon discourages users from handling traffic on ports below 1024, so we’ll redirect traffic coming into port 80 to another port that your application listens on. In Leaf’s case, that port is 8080, but you can use practically any port you like.

sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

Run your application

Typically, running a Node application is just throwing a “node” in front of the JavaScript file you’d like to execute. That still works on an EC2 instance, but as soon as you quit your SSH session, the Node executable will exit. To get around this, the guys over at Nodejitsu have built a Node plugin called Forever which solves exactly our problem. First, install forever.

npm install forever --save

Once installed, tell Forever to run your script as so, assuming it’s called “server.js”.

./node_modules/forever/bin/forever 
start 
-al forever.log 
-ao out.log 
-ae err.log 
server.js

If you ever need to stop your script, you can do so this way:

./node_modules/forever/bin/forever stop server.js

Fin

And that’s it. Pretty straightforward stuff. You can test that your application is visible by navigating to the public DNS location (or public IP) that your Amazon EC2 instance is set to. Piece of cake!

Thanks for reading!