NodeJS, Websockets and EC2

I’m working on a project that involves websockets and needed to set up a test server. If you are looking for a server to do nothing but websockets and run node.js than this is you’re tutorial.

We’ll be setting our environment up on EC2, our stack will consist of node.js running on port 80 (requires root) and some software we might need.

Let’s set up the environment first.

Launch the following instance:

ebs/ubuntu-images/ubuntu-maverick-10.10-i386-server-20101225 (ami-ccf405a5)

We don’t care where its location and have no preferences on security groups or anything. NOTE: This environment is not intended for production, there will be many security holes with our setup, but if your looking to get something up and running for prototyping…this is super quick.

UPDATE: if you are having trouble “sshing” to this shitty server, follow the tutorial here.

SSH and do:

ssh ubuntu@YOUR_INSTANCE_IP -p22
sudo apt-get update

Then:

sudo apt-get -y upgrade

Let’s get rcconf – we won’t use it, but it might be helpful to you later on…

sudo apt-get install rcconf

Now let’s install some essential packages:

sudo apt-get install build-essential
sudo apt-get install libssl-dev
sudo apt-get install git-core

At the time of writing this, the current version of node (0.5.5) has a problem with the most recent version of npm – so we’ll install a good stable version of node (0.4.10). This way we know we’re getting something that works. Install node:

wget http://nodejs.org/dist/node-v0.4.10.tar.gz
tar xzf node-v0.4.10.tar.gz
cd node-v0.4.10
./configure --prefix=/usr
make
sudo make install

Now let’s install npm:

cd ~
git clone http://github.com/isaacs/npm.git
cd npm
sudo make install

Now for the fun stuff. Let’s get some cool packages from npm:

cd ~
npm install connect redis connect-redis jade express express-resource futures emailjs socket.io http-proxy

Let’s make a web folder:

cd ~
mkdir ~/www
cd ~/www
pico server.js

Enter the following into server.js:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello Worldn');
}).listen(80);
console.log('Server running at http://127.0.0.1:80/');

Run the node server and visit your instance’s IP address:

cd ~/www
sudo node server.js

You should see a “hello world” appear at the top of the page. This indicates your node server is running properly. Now its time for use to configure our server a bit more test our web sockets. Let’s make sure web sockets are running before we do anything else.

Now let’s stop the node server for a second so we can do some more work. Hit “Ctrl + c” to kill the process.

Create “index.html”:

pico ~/www/index.html

And fill it with (remember to replace YOUR_IP_ADDRESS with your instance’s IP):

<html>
	<head>
		<title>Node</title>
	</head>
	<body>
		<script src="/socket.io/socket.io.js"></script>
		<script>
		  var socket = io.connect('http://YOUR_IP_ADDRESS');
		  socket.on('news', function (data) {
		    console.log(data);
		    socket.emit('my other event', { my: 'data', another: 'more data' });
		  });
		</script>
	</body>
</html>

Now open server.js:

pico ~/www/server.js

And replace the contents with a websocket server:

var app = require('http').createServer(handler)
  , io = require('socket.io').listen(app)
  , fs = require('fs')

app.listen(80);

function handler (req, res) {
  fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

Now let’s test it:

cd ~/www
sudo node server.js

And visit the IP of your instance in a web browser. Nothing should appear on the screen, but if you look in your terminal you should see data being transferred. Additionally, if you inspect the element (chrome or Firefox) and refresh the page, data should appear in the “console” tab.

Great, now that we have websockets working, let’s get FTP up and running so we can start to make some changes. Kill the node server again by running “Ctrl + c”.

Let’s install vsftpd, which is the most popular FTP server on Linux:

sudo apt-get install vsftpd

Now we need to edit the configuration file to get it running:

sudo pico /etc/vsftpd.conf

Add the following lines to the end of the file:

pasv_enable=YES
pasv_min_port=1024
pasv_max_port=1048
pasv_address=107.20.254.40

Make sure in your security group for the instance that you have opened ports 21, 22 and 80 for FTP, SSH and HTTP respectively.

Also make sure you enable the following line:

# Uncomment this to enable any form of FTP write command.
write_enable=YES

Now we can restart vsftpd:

sudo service vsftpd restart

However, we haven’t set up any sort of password for our user yet. We should be running all our commands under the default “ubuntu” user. That’s ok, lets just set a password for root and for our friend Ubuntu:

sudo passwd

Then enter in your new password for root. Then set the password for “ubuntu”:

sudo passwd ubuntu

And enter Ubuntu’s password.

We should now be able to FTP to our instance at ftp://YOUR_INSTANCE_IP/ with the username “ubuntu” and the password you just set.

To recap, in about 15 minutes (not counting the time it takes to make and install node and npm) we have set up a shiny new Amazon instance, installed node and enabled web sockets. Set up FTP service and have access to change files.

References: Installing FTP on EC2, Socket.io getting started, inspiration for this article, there also a great post here.

Congratulations!

UPDATE: If you don’t want to go to the trouble of setting up a server environment to run node, you could just use this: http://jsapp.us/

5 thoughts on “NodeJS, Websockets and EC2

  1. Great Tutorial thanks for writing this! I’m not a linux expert and your instructions were clear enough that I never got stumped.
    Note that I used the latest node.js 0.6.18 and it appeared to work fine with the latest NPM. I used Amazon’s Ubuntu Server image cause I didn’t know where to find that maverick one.

Leave a Reply

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