Node.js development stack on Amazon EC2

Recently, I needed to create node.js development stack. I was using Nodejitsu for my development, but it became more expensive. I was experimenting with AppFog but I decided that I give a try to Amazon Elastic Compute Cloud as I’m already using Amazon S3 storage for my iStitch App and Amazon Route 53 for static hosting of dennikrss.net.

My goal is to run node.js app behind nginx. Static files will be (in future) served from Amazon S3. The second goal is not to spend to much time with maintenance of the stack. I’m a developer so I don’t like to spend too much time with maintenance. I like “fire and forget” solutions.

This is basically a cookbook for me, but if it helps someone I will be more than happy. Process of installation is divided into this simple steps:

  • create Amazon EC2 instance
  • install node.js & nginx
  • configure nginx as a reverse proxy
  • run sample node.js application (express app)

Create Amazon EC2 instance

Creation of EC2 instance is pretty straightforward process. First you need to access Amazon AWS console (I’m assuming that you have Amazon account):
amazon_01

Go to EC2 Dashboard and choose region. I choose Ireland.
amazon_02

Go to instances in menu and click on “Launch Instance”.
amazon_03

Click on “Classic Wizard”.
amazon_04

I’m using Amazon Linux (64bit). If you chose something else, it’s your choice, but this guide is only for Amazon Linux.
amazon_05

Click next, next, next until you get to “Key Pair” screen.
amazon_06
amazon_07

On this screen create key pair (if you’ve already created one, just use created on). This key pair is different from key pair that you can use on other Amazon services (eg. S3). You will need downloaded file later, so don’t delete it.
amazon_08

On “Configure firewall” screen create Security group and add HTTP rule so you can access your EC2 instance on port :80. It also can be configured later.
amazon_09

Click “Launch” and wait. It takes few seconds to boot your EC2 instance.
amazon_10
amazon_11

Click on your EC2 instance and you will see on the bottom of the screen your EC2 instance address. This address is important. With this address, you can access your EC2 instance later through ssh or with http (web browser).
amazon_12

SSH accesss

Add downloaded .pem file to ssh (I’m using Mac OS X):

$ ssh-add -K ~/YOUR_KEY_NAME.pem

Remember that your key needs to have appropriate permission. If not, you will get something like this:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/Users/USER_NAME/YOUR_KEY_NAME.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.

Change permissions

$ chmod 600 ~/amazon-ec2-ireland.pem
$ ssh-add -K ~/YOUR_KEY_NAME.pem

Connect to your EC2 instance:

$ ssh ec2-user@EC2_URL_YOU_GET_FROM_AWS_CONSOLE.amazonaws.com
Warning: Permanently added '*************************************************************' (RSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2013.03-release-notes/
-bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory
[ec2-user@... ~]$

So now you have ssh connection to your EC2 instance.

Install node.js & nginx

Install nginx, gcc-c++ make, openssl-devel and git with yum:

[ec2-user@... ~]$ sudo yum install nginx
[ec2-user@... ~]$ sudo yum install gcc-c++ make
[ec2-user@... ~]$ sudo yum install openssl-devel
[ec2-user@... ~]$ sudo yum install git

Clone node.js and npm repository into ~/ folder and make node and npm:

[ec2-user@... ~]$ cd ~/
[ec2-user@... ~]$ git clone https://github.com/isaacs/npm.git
[ec2-user@... ~]$ git clone git://github.com/joyent/node.git
[ec2-user@... ~]$ cd ~/node/
[ec2-user@... ~]$ git checkout v0.10.8
[ec2-user@... ~]$ ./configure
[ec2-user@... ~]$ make
[ec2-user@... ~]$ sudo make install
[ec2-user@... ~]$ cd ~/npm/
[ec2-user@... ~]$ sudo make install

Add /usr/local/bin path to /etc/sudoers:

[ec2-user@... ~]$ sudo nano /etc/sudoers

Find secure_path and add :/usr/local/bin at the end of the line:

...
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
...

Save your changes.

Check if node and npm are installed properly

[ec2-user@... ~]$ node -v
v0.10.8
[ec2-user@... ~]$ npm -v
1.2.21

Check if nginx is installed and configured properly

[ec2-user@... ~]$ sudo chkconfig nginx on
[ec2-user@... ~]$ sudo service nginx start

When you type adress of your EC2 instance into the browser, you should see something like this:
nginx_01

Configure nginx as a reverse proxy

[ec2-user@... ~]$ sudo nano /etc/nginx/nginx.conf

Find “location / {…” and replace it like this:

...
#location / {
#    root   /usr/share/nginx/html;
#    index  index.html index.htm;
#}
location / {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}
...
[ec2-user@... ~]$ sudo service nginx restart

Run sample node.js application

Install express package with npm and create test application in ~/projects folder.

[ec2-user@... ~]$ sudo npm install express -g
[ec2-user@... ~]$ mkdir ~/projects
[ec2-user@... ~]$ cd ~/projects
[ec2-user@... ~]$ express --ejs testapp
[ec2-user@... ~]$ cd testapp && npm install
[ec2-user@... ~]$ node app

If everything is installed and configured properly, you should see express test application when you type EC2 instance url into the web browser
express_01

If you have any questions or problems with an installation, feel free to ask. I will try to answer any question and help with any problems.


Continue to: Keeping node.js dev stack up to date on Amazons EC2

22 thoughts on “Node.js development stack on Amazon EC2

    1. Miroslav Magda Post author

      Which version of nginx do you have (nginx -v)?

      nginx 1.3.13 has support for websockets. If you have lower version than 1.3.13 then socket.io will “falback” to xhr polling. and thats why its slow…

      Reply
  1. Tiafau

    I’m stuck on SSH access, specifically connecting to my EC2 instance. Can anybody help asap? I keep getting an error message like the following:

    ssh: connect to host ec2-EC2_URL_YOU_GET_FROM_AWS_CONSOLE.amazonaws.com port 22: Operation timed out

    Thanks!

    Reply
    1. Miroslav Magda Post author

      You need to replace EC2_URL_YOU_GET_FROM_AWS_CONSOLE.amazonaws.com with the address from your AWS console.
      When you click on your instance in the AWS console you should see “public DNS” entry there. Copy it and then use like this: ssh ec2-user@PUBLIC_DNS_ADDRESS.
      It should work.

      Reply
      1. Tiafau

        Thanks. I’ve gotten now to the “Configure nginx as a reverse proxy” part. How do I know it’s working?

        I replaced…

        location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        }

        with…

        location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection “upgrade”;
        proxy_set_header Host $host;
        }
        and now when I refresh the IP address, nginx site gives me this error: “The page you are looking for is temporarily unavailable. Please try again later.”. Did I do something wrong?

        Reply
          1. Miroslav Magda Post author

            It depends what you want to do with EC2. EC2 is just a virtual server. This guide describes how to install and configure node.js with nginx.
            You can instal whatever you want on EC2.

  2. Tiafau

    I’m still getting an nginx error when I replace the default code

    location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    }

    with

    location / {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection “upgrade”;
    proxy_set_header Host $host;
    }

    Any idea why it’s not working?

    Reply
  3. Tiafau

    How do I make it so anytime I close terminal, it doesn’t shutdown the server? Everytime I close terminal, the server on port 3000 (where location proxy is) closes and my app in response, shuts down.

    Reply
  4. prathyush

    Hi,
    That was very helpful but i want to run applications that are present on my local computer on amazon ec2 instance.Can any one please tell me how to do it.I’m very new to this.

    Thanks in advance for any help.

    Reply
  5. Siddhartha

    I’m getting the following error when I run “node app” command:-
    module.js:340
    throw err;
    ^
    Error: Cannot find module ‘static-favicon’
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object. (/home/ec2-user/projects/testapp/app.js:3:15)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)

    Reply
  6. Fahad Rafiq

    Great, but if you need to host any php apps or framework in Amazon ec2, so Cloudways offer in their Platform.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *