Category Archives: Node

Amazon EC2, Nodejs, Tmux quick reference

Just a quick post so I remember what I did and how to do it again:

Set up an AWS EC2 instance:

Sign up for / log in to Amazon Web Services. When you get to the main screen full of icons, select EC2 (stands for Elastic Cloud Computing — elastic because its easily expandable). Then click through many screens. This time we selected an Ubuntu 12.something 64-bit instance, and we chose the smallest (free-est) stuff possible; I believe it was called a micro instance or something. When you have to set up ports and such, the two important ones (if you’re planning on setting up some testing web host, for example), are ssh and http. Both are of type TCP, and it’s okay to let them accept all IPs for now. Next up, I think you have to set up your ssh key. Amazon will create one especially for you. Download it and put it in a safe place. Don’t lose that key or you’ll have to redo everything from scratch. Okay, now that you’ve got your ssh key, keep clicking okay/launch until you get to a screen that shows what might be a list of running instances (at this point I/you only have one going). If you scroll to the right, you’ll see the Public DNS and Public IP for this running instance. You should also see a green circle under instance status that says it’s running. Excellent! Perhaps copy that Public IP address, for we’ll need it to ssh into our server.

Log into your shiny new instance:

Great! Now let’s ssh in. To do so, first you’ll need to change the permissions on your ssh key file to make it more exclusive.


Aside on File Permissions:

File permissions are a cool relic of cleverly storing large(ish) amounts of data in small ways. Permissions are made of three digit numbers which represent the User’s permissions in the left-most digit, the Group permissions in the middle digit, and the Others permissions (world? I dunno) are represented by the right-most digit. The file permissions for each user/group/whatever are represented (each digit) by adding up the permissions you are granting (0 – nuthin’, 1 – execute, 2 – write, 4 – read), so read-write-execute (rwx) is 7 (4 + 2 + 1), while read-write (rw) is 6 (4 + 2), and so on. For our purposes, we (the main user) would like to be able to read, write and execute our ssh key (honestly, all we need to be able to do is read it, but this is fine too), and we DON’T want others to have any permissions on it, so we’ll set our permissions to 700 (7 for us, 0 for group, 0 for everyone else). To do so, we go to the directory that we stored our ssh key in and type “chmod 700 filename” where filename likely ends in pem and is the name of our ssh key file. Done.


… back to logging in to our EC2 instance

Now that our permissions are more exclusive, let’s ssh in: “ssh -i ./path/to/sshkeyfile ubuntu@ipaddress” where ubuntu happens to be our default username since we have an ubuntu instance and ipaddress is the public ip address listed in that table in the EC2 Management Console that we were in two paragraphs ago. If all goes according to plan, you should see your new shell prompt: ubuntu@ip-###-##-##-###:~$. Now you can install whatever you need to feel happy using apt-get:

apt-get-GOING:

Type “apt-get update” to update your default package manager (apt-get). [NOTE: you will likely need to sudo the apt-get commands.] First up, I installed git: “sudo apt-get install git”. Next up, I installed nodejs: “sudo apt-get install nodejs” and npm: “sudo apt-get install npm”. You get the idea. Now you should be able to “git clone https://github.com/yourUsername/yourRepo” and fetch yourself your project files. In order to run a server (such as node), you’ll likely have set up environmental variables (perhaps I’ll write a post on this someday soon, as I have recent mildly-hellish-but-ultimately-successful experience setting up env vars on heroku). To set environmental variables in bash you could either type them all out (“a=1”; “echo $a” => 1 to confirm) then run your server, OR you could write a bash script that you call. Here’s how I did that:

lil’ bash script to set environmental vars:

Your ubuntu instance comes with vim, so you can type “touch .env” to make the file, then “vim .env” to open it for editing.


Very quick Vim intro aside:

Vim in short: it has modes. Press “i” to begin editing (now you’re in INSERT mode, as you’ll see at the bottom), or the escape key to go back to COMMAND mode. Typing “:wq” in command mode will save your file and quit out of vim. That’s all that’s necessary here.


… back to a bash env script:

Now that you have your .env file open in vim for editing, type commands as you would in bash. You’ll likely want to set things like “PORT=80” and on a newline “CLIENT_SECRET=yourcrazyapistring”, etc. Once you’ve typed in those important things that your app will need to know to run, save and get out of vim (esc, “:wq”). Now, run your .env file by typing “source .env”. [NOTE: you can also run it with “bash .env” but that will run it inside a tiny bash instance that will run the given script then exit, without keeping what you’ve set as fact in the current instance of your bash shell, which is why we’re instead using the source command.] Grrreat! Now you can run your server (in my case, cd to the folder my app is in and type “node app.js”).

On tmux

Okay, so far, so good, but what happens when we control-C and log out of our ubuntu server? It powers down! Or rather, once we log out of our bash session, whatever web server we’ve started in there will stop. So. We need a way to trick it into staying open even if we are not logged in: enter tmux. Tmux will let us begin a session and detach from it, letting it run by itself. [NOTE: at this point, if we’re really going to run a real website, we would do a lot of other things instead, such as install and use nginx, but that’s for another day.] So, how do we use tmux? First up, install it “sudo apt-get install tmux”. Then run it: “tmux”, which gives us a cute little bash-within-a-bash from which we can do normal things. (To get out: type “exit”). Within tmux, use the command initiator key combo (control-b) to do things. For example, type control-b then “?” for the help. The cool part of tmux is that you can now detach from a session you have going by typing control-b then “d”. Now you have a detached session within which you could have your app server running. Try logging out of your ubuntu instance (control-c) and back in (ssh command in bold above) and then type “tmux attach” and you should be back into your detached session! How cool is that?!? (very cool). I think you can also name sessions and do a bunch of fancy stuff with tmux that I don’t know about. I did, however, find out how to list your active sessions (“tmux ls”) and kill them one-by-one (“tmux kill-session -t sessionnumber”) where sessionnumber is the number of the session listed when you type “tmux ls”. BAM!

SCP – Secure CoPy

Alright, one last tidbit: how to get files onto your new ec2 instance. Tricky. It seems that within terminal you are either looking at your own local machine or you are ssh’ed into another machine. Thankfully, there’s a secret bridge between the two: scp, which stands for secure copy. Here’s how it works: within terminal, in bash on your local machine, type “scp -i ./path/to/your/sshfile.pem ./path/to/file/youwanttocopy/onlocalmachine ubuntu@##.###.###.##:/home/ubuntu”. Let’s explain: “scp -i” means tell secure copy to use your identity file (your sshkey); “./path/to/your/sshfile.pem” the path to your ssh file on your local machine so that scp can connect securely to the remote computer; “./path/to/file/youwanttocopy/onlocalmachine” the path to the file (on your local machine) that you’d like to copy to the remote machine; “ubuntu@##.###.###.##:/home/ubuntu” remote username (default in my case is ubuntu) AT remote ip address, colon, existing file path on remote machine.

Okay, I think that’s all I learned from 9am – 10am today. Amazing!

Hacker School Day 10: About TCP/IP & a Node.js Hello World

.Where. .to. .begin. .?.

I began today slightly bored of Nefario Teaches Typing. There’s a WHOLE lot more I could do with it, but I won’t learn anymore by doing those things. I mean, sure, I’d get a little faster at some simple stuff, but I’m ready to be CHALLENGED, PUZZLED, PERPLEXED. So I put that on the shelf for now (I think I’ll still work on it in the evenings, as a little side-project) and sought some facilitator advices. M suggested that I either delve into a meaty client-side project such as a drum music simulator thing or that I try to write my own super-simple, crappy web server. Since I know little (NOTHING) of sockets and such, I figured that’d be a worthy pursuit. I proceeded to spend the rest of today reading up on Node.js, packets, sockets, TCP/IP, and other bizarre terms. From this, I think I’ve extracted a bit of knowledge. Please see below:

TCP/IP

The what? TCP stands for Transmission Control Protocol. That means nothing. What they should call it is: Reliable Communication Command Center, the RCCC. Because that’s what it does. TCP is a protocol (read: set of rules or instructions) for sending and receiving lil’ packets of info between and within computers. [NOTE: feel free to well-actually me in the comments: I won’t be offended, I’ll merely learn better.] Okay, so, from what I understand, TCP works with the IP (Internet Protocol, another set of instructions) to coordinate communication between computers in packet-switched networks.
“What’s a packet-switched network?” I’m glad you asked! It’s when things (computers in this case) transfer data in little packets instead of via a constant bit stream. This means: you can send some data then stop, then send more; the packets can travel via different routes to get to the same place; you can check for errors in delivery, and you can grab data from multiple hosts (computers serving up data). Packets are great! Let’s talk more about what a packet actually is:

Packets

Packets are like datagrams, but not quite. Datagrams are little chunks of data, packed light for travel. Datagrams contain some header info about where they’ve come from and where they’re headed and what type of data they contain, then they have some sort of body of data, called the data payload. I picture this as a Chinese Dragon head that barfs up addresses and types, stuck to a dump-truck of solid gold data bars. (It’s been a long day.) The thing about datagrams is they don’t pay attention to their own survival. They contain no way to tell whether they’ve reached their final destination, and no data about error-checking for their missing friends or limbs. No guarantees! Sent then forgotten. Packets, on the other hand, are souped-up dragon-trucks: in addition to the basic datagram info, packets also contain info about which of them belong together and in what order, and they (somehow) have ways to instruct their receiver about how to test them for errors (I think this has to do with some magical size computation that would detect missing data).

IP Addresses

This is just cool. You know how when you get your IP address it just seems like a bunch of numbers? Well, it is, but there is a little logic to it. Everything in the header of these packets has a specified (by the protocol) amount of data it can take up, which I imagine makes it easier to parse and such. The amount allotted for an IP address is 4 bytes (each 8 bits long), which means the “address” is 4 “numbers” long, each separated by a period, each between 0 and 255 (which are all the numbers you can make with 8 bits: 00000000 – 11111111), hence something like 127.0.0.1. Cool, huh? I thought so. Also, IP addresses are the personal address of your computer. Something like that.

Node.js

Today I read a bunch about node and learned how to write the teeniest web server. Here it is:

// require the http module in node:
var http = require('http');

// write a listener function that will do something (send a response, ideally) when the server receives a request:
var webListener = function (request, response) {
    if (request.method == 'GET') { // what to do if this is a GET request (most are!)
        console.log("Request was a GET"); // just tell the terminal that it was a get request for now
        console.log("URL: " + request.url); // tell me that url, please!
    }
    response.writeHead (
        200, // that code means the request was successful, tell the client "200, yay!"
        { 'Content-Type' : 'text-plain' } // We're going to send back some plain ol' text
    );
    response.end('Hello World!'); // end our response with the data (text) that we want to send back
}

// make a new instance of the server object and pass it our fancy listener function from above
var server = new http.createServer(webListener);

// tell the server to listen up! (and give it a port number to listen on and a host to use -- localhost)
server.listen(8124, "127.0.0.1");

// tell me you're working, server!
console.log("Server running at http://127.0.0.1:8124");

Oh right, first install node (use homebrew!). Then put the above code in a file, and call it example.js. Save it somewhere, navigate to that place in Terminal (someday I’ll write a super-teeny Terminal intro), then type “node example.js”. BAM! Web server, up n’ runnin’.
Phew! That’s it. I’ll go into more detail tomorrow about what the particulars of each of these are, but in general, the client (your computer) connects to a host (now my computer) and they say “coo’, let’s talk.” So your client computer requests something from mine (you want to see my website, of course) at the address that is my computer, connected to the port that my server is listening to. My server gets that request and responds however I tell it to (in this case by sending you back “Hello World!”). Tomorrow’s goal: send back an html file. I guessed that I would have to read a file’s content into some sort of buffer and send it appended to a packet, and I think I’m right. I haven’t yet looked too far into the details of that, but I’ve got a general idea of how it’ll work.

Stay tuned, folks! And thanks for reading.

FORGOT! Here’s my illustrated understanding of TCP and IP:photo