Deploying Node Apps with AWS
For my first post in weeks, I'm going to address a very exciting topic: how to deploy Node apps through Amazon Web Services (aws)! I’m going to assume for the purposes of this guide that you have already purchased a domain (I like Hover for this) and linked it to the AWS nameservers. I'll be using my site nflTweets as an example throughout this post.
Set up a server
Our first step is to set up our server. We are going to use a virtual server through Amazon’s EC2 service. From the EC2 dashboard, find that big blue button that says “Launch Instance”. It lets you launch an instance, who knew?
Next, we’re have to choose an Amazon Machine Image (AMI). The AMI contains the OS and software we will use to launch our instance. We will be using a ubuntu-based AMI made by my instructor Chyld Medford. This will save us a lot of headache because it has Node and Mongo already installed, along with other configurations we won’t have to worry about. Thanks Chyld! To select this AMI, click “Community AMIs” from the tab on the left and search “chyld”.

Next, we have to choose the instance type we want. The more powerful the instance, the more our server will be able to handle. For our purposes the t2.micro will suffice. It doesn't hurt that it’s free, either. We wont be changing anything in the ‘configure instance’ or ‘add storage’ screens, you can click next on each of those. At step 5 you will be asked to give your instance a ‘name’ tag. Call it whatever you want.
On step 6, ‘Configure security group’, we will be making some changes. By default, only SSH is configured (using port 22). We obviously want to allow HTTP requests, and this is simple to do. By clicking ‘add rule’ and changing the type to HTTP, we will open up port 80 to requests. We can leave both rules open to requests from any IP. SSH requests will need a key, and HTTP requests are what we want. On the final ‘review and launch’ page, aws will give us a warning about leaving our instance “open to the world”. We will ignore that for now.

When we click launch, there is one last important step. Amazon will ask us to select a key pair to use to access our server. If you don't already have one, you can generate a new key pair which will be permanently associated with this server. It will prompt you to download a .pem file. This is our key. We need this file to ssh into our server. Don’t lose it this .pem file. Back it up. Seriously. We now have our very own server up and running! Give it a few minutes to initialize.
Set up a static IP
Now that we have a server, we need a static IP. This is where we will point DNS services. From your EC2 dashboard, click on “Elastic IPs” under “Network and Security”. Allocate a new address, then select it and click “associate address”. A box will pop up, in the ‘instance’ field select the vps you just set up. The address listed under Elastic IP is now the IP for your server. Easy peasy lemon squeezy.
Configure Route53
Route53 is what Amazon calls its DNS service. Actually they call it a “scalable domain name system”, whatever Jeff Bezos. Go back to the AWS console, and click Route53. Go to your hosted zones (or create one), view the record sets for your domain name. We are going to set up an A record on a subdomain whos value is the IP we just set up.

Deploy!
It’s time to ssh into our server! One thing first though. Open your terminal, navigate to the directory which has your .pem file and use the following command.
chmod 400 *.pem
This changes the file permissions on our key to be read only, this is necessary for our server to accept it. Now it’s actually time to ssh. Like so :
ssh -i <filename>.pem ubuntu@nfltweets.mikeyb.net
Because we have configured our DNS service with an alias, we dont have to the use the IP, we can use our domain name. If the DNS record hasn’t propagated yet, you can use the ip. Obviously, substitute it with your sites address. If you successfully ssh’d you are now controlling a virtual machine in an Amazon server farm thousands of miles away, how cool is that!
Get it on there
Thanks to the bash profile Chyld put on our AMI, you can use the ‘code’ command to navigate directly to ~/apps/code. You may notice there is already an app here called ‘proxy’, we’ll get to that later. For now clone the git repo of your app. You probably know how to do this, but just in case:
$ git clone <github.com/<username>/<repo>
The next step is a bit up to you. You have to get your app set up. This often involves a good old fashioned npm install, maybe a bower install, maybe a grunt command, database seeding etc. Do all that.
Now we can test our app, spin it up using whatever command you use to host it locally, choose whatever port you want (except 3000, proxy is using that). For me this looks something like this:
$ PORT=5000 DB=nflTweets node server/index.js
If you go back to the security group of your instance, and open that port with a new custom TCP rule.

Now if we navigate to <subdomain>.<domain>:<port> (for me its nfltweets.mikeyb.net:5000) we can see our app live and running!
But we don’t want to have our users putting in a port whenever they want to use our site, that’s what proxy is for. If you are satisfied with how your site is configured, go ahead and close that port for security reasons.
Setting up proxy
Proxy is a simple little program. Navigate to ~/apps/code/proxy/app to find the two files that comprise it: index.js and proxy.json. We are going to edit proxy.json, so I hope you know vi! Proxy.json contains (surprise!) a simple JSON object, the keys of which are domains and the values of which are the port to route them to. Edit it so that your domain points to your port. eg:

pm2
The last step is to get our app and proxy running together, in the background. We will be using a program called pm2, a process manager for node. This is pretty easy, all you need to do is start your app as normal, but replace ‘node’ with ‘pm2 start’. eg:
$ PORT=5000 DB=nflTweets pm2 start server/index.js --name nflTweets
//and for proxy, from the app folder:
$ pm2 start index.js --name proxy
And there it is! The —name command gives your processes and id for pm2. Use ‘ pm2 list’ to make sure the processes are running. Now pm2 should keep your app running as well as proxy. Proxy will listen to port 80 and route requests according to proxy.json.
You should be up and running! You can use ‘pm2 logs’ to see your server logs.
Thanks for reading. This is obviously a pretty specific guide, but using Chyld’s AMI makes deployment much easier. I hope you found this useful. I promise to write more regularly going forward ☺
-Mikey