Laura Diane Hamilton

Technical Product Manager at Groupon


How to Set Up a Node.js Web Server on Amazon EC2

If you've never done it before, it can be a bit tricky to navigate Amazon's "security groups," Linux's firewalls, and ip forwarding. I've created a tutorial to demonstrate, step-by-step, how to set up a skeleton Node.js app on Amazon EC2.

First, create an account on and set up two-factor authentication.

Next, click on EC2 - Virtual Servers in the Cloud. (EC2 stands for "Elastic Compute Cloud.") In the left-hand nav, click on "Instances." From the next screen, click the button "Launch Instance." If you are a new user, you can run a micro instance for free for a year.

Select the "Quick Launch Wizard," give your new server a name, and create a new key pair. Download your key. The key basically secures the server, so that only you can ssh onto it. Be sure to keep your key safe. For this demo, I chose to use Ubuntu 13.04, but any relatively recent Linux flavor should work fine.

Next, move your ssh key from your Downloads folder to someplace more permanent: mv ~/.ssh Check it's in the new place: cd ~/.ssh ls

Now, it's time to ssh onto your server. Check the tick-box next to your server name. You should see your server name — something like You'll need this name to ssh on: ssh -i ~/.ssh/key_for_nodejs_demo_server.pem Oops! That didn't work. You need to restrict the permissions on your key_for_nodejs_demo_server.pem file so that only your user can access it — not anyone else on your computer. chmod -R 700 ~/.ssh/key_for_nodejs_demo_server.pem Now you can ssh. ssh -i ~/.ssh/key_for_nodejs_demo_server.pem Now, you should see that your command prompt changed, indicating you're now on the EC2 server. You should see something like this: ubuntu@ip-10-164-108-235:-$

If you don't already have a github account, you should sign up for a free one.

Next, it's time to install some programs we're going to need. First, install git (for version control): sudo apt-get install git Sudo, which stands for "superuser do," and will run a command as root. You need to use sudo in order to install programs. Now verify that git is installed: which git

Next, let's fork the heroku/node-js-sample repository. Fork it via the github web interface; this will essentially make you a copy of the repository. Now clone the repository you just forked, so that you put a local copy of the source code on your EC2 machine: git clone Now change directories into your new repo: cd node-js-sample And take a look at the files in your skeleton app: ls

Let's try to run the app now. node web.js Oops! Looks like we need to install node first. sudo add-apt-repository ppa:chris-lea/node.js sudo apt-get update sudo apt-get install nodejs Make sure that you install the latest version. Sometimes ubuntu will install an older version, which you do NOT want. node --version Make sure that you see version 0.10.13 (current version at the time of this writing) or higher. You can find the current version of node.js here.

Let's try to run our app again: node web.js OK, a new error this time! That means we're making progress. module.js:340 throw err; Error: Cannot find module 'express' This means we need to install a node package manager, and the required packages. npm install express

Now, let's try our server again. node web.js You should see a message "Listening on 5000." The web server is up and running now!

Try to visit your web server by pasting its url into your browser: This won't work. We need to open the right ports first.

Back in your AWS management console, select your instance, then in the "Network & Security" section click on "Security Groups." Select your instance's security group (it will be something like "quicklaunch-1". Open up port 80 (http) to allow connections from all ip addresses. Be sure to apply your changes (doesn't happen automatically). Now, you should have three security groups, like this:

Let's change the app to listen on port 8080: vim web.js Change the port from 5000 to 8080. For security reasons, we're not going to allow any connections on ports below 1024. Now, in order to allow requests on the standard HTTP port, 80, let's set up some port forwarding. First, run this command to see if you have ip forwarding enabled already: cat /proc/sys/net/ipv4/ip_forward If it returns 0, then ip forwarding is disabled. A 1 means it's enabled. sudo vim /etc/sysctl.conf In this file, uncomment this line: net.ipv4.ip_forward This will enable ip forwarding. Then, to enable the changes made in sysctl.conf: sudo sysctl -p /etc/sysctl.conf Now, let's check that ip forwarding is enabled: cat /proc/sys/net/ipv4/ip_forward That should return a 1 now.

Now, let's set up forwarding from 80 to 8080: sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

Next, we need to open the Linux firewall to allow connections on port 80: sudo iptables -A INPUT -p tcp -m tcp --sport 80 -j ACCEPT sudo iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT

Now, let's try starting our app again: node web.js It should say it's "Listening on 8080."

Now, in your browser, enter the public ip of your EC2 machine (e.g., It should greet you with, "Hello, World!" Congratulations, you have a node.js server up and running! is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to