Raspberry Pi NodeJS Project Setup with Git Deployment

Now that my Open University studies have finally finished I have some free time again! I've had my Raspberry Pi pretty much since they first came out and apart from using it to run XBMC I've not done much with it. So now I've decided to do a project with it; yay! I shan't reveal what it is yet but it will be "Internet of Things" type of "thing" and running NodeJS!

Requirements

Before I started my project I wanted to setup my pi and create a workflow. This is what I wanted from the setup:

  • NodeJS
  • Write the code on my Hackintosh
  • Easy & fast deployment (especially no FTPing files around)

Why Node? I've got along with Node well recently, I wanted to use it on a project rather than just dicking about and there seems to be plenty of packages available for interacting with the GPIO pins.

If that's all I was after I could use something like the excellent looking pijs.io but I want to write my code on my main machine using my vim setup. Also apparently I don't have a monitor with HDMI input or spare keyboard to work directly on the pi.

Finally easy and fast deployments, heroku style. I want to be able to do a Git push which deploys the code and runs it up on the pi.

Basic setup

As mentioned above I'm using OS X so if you want to follow along you might have to adapt some of the steps especially if you are on Windows, mainly you'll just need a SSH client and Git though.

First thing is to create the bootable SD card, the official raspberry pi documentation for installing images is excellent and has steps for Windows, OS X and Linux:

Installing Operating System Images

I installed the Raspbian Debian Wheezy image.

Next we need to find the IP address we can connect to, the 3 strategies were:

  • Plug it into television or monitor with HDMI cable (easy as the pi tells you it's IP after booting up if this is an option for you)
  • Note down all the IP addresses connected to your home router, plug in the PI and see what the new IP is (some home routers have this)
  • Ping everything in your subnet and see what's running SSH

I ended up doing the last option :(

Pro tip:  
Find your main computers ip address and subnet and you can then get OSX to list all devices responding to ping! For instance if your IP is 192.168.1.100 and subnet mask is 255.255.255.0, pinging 192.168.1.255 will show other IPs. Your mileage may vary with this one...  

Once you know the IP say (192.168.1.90) connect to it with SSH:

$ ssh pi@192.168.1.90

The default password is: raspberry in case you didn't read the bit at the downloads page ;)

Next we want to run the raspbery pi configuration tool:

$ sudo raspi-config

I chose to:

  • Expand Filesystem
  • Change User Password
  • Enable Boot to command-line

You might want to do other configuration as you see fit but this seemed enough for my purposes, especially ensuring boot to command line, we don't need no GUI sucking up all the resources.

After the restart (if expanding filesystem) let's make sure we're all up to date:

$ sudo apt-get update
$ sudo apt-get upgrade

Lovely!

Installing Node

Now you can either compile Node from source but this takes a while, alternatively you can do this:

$ wget http://node-arm.herokuapp.com/node_latest_armhf.deb
$ sudo dpkg -i node_latest_armhf.deb

This will only take couple of minutes and at the time of writing it installed 0.10.32-1. You can check that the install was successful and what version you are running:

$ node --version

Next we'll install a tool called forever. It's a simple command line tool that runs your script and restarts it when it finishes running for any reason such as if it crashes out.

$ sudo npm install forever -g

This might take a bit of time so time for cuppa or if that's not your thing, drop me a line on twitter @efexen and tell me what you think so far ;)

Setting up deployment

First we'll setup a bare git repository:

$ mkdir -p ~/testing_app.git
$ cd ~/testing_app.git
$ git init --bare

This initialises a new repository but without a working directory (it'll look like what you would normally find in the .git directory).

Next lets create a folder for where the deployed app will live and run:

$ mkdir -p ~/apps/testing_app

Next install a text editor you're happy to write a short script on, I highly recommend vim:

$ sudo apt-get install vim

Now lets create a post-receive hook, sounds fancy but it's just a shell script that will run after code has been pushed to the repository.

$ cd ~/testing_app.git/hooks
$ vim post-receive

Here's one I made earlier:

#!/bin/sh

DEPLOYDIR=~/apps/testing_app

GIT_WORK_TREE="$DEPLOYDIR" git checkout -f

cd "$DEPLOYDIR"

forever stop index.js

npm install

forever start index.js

echo "All done ;)"  

So what's going on here?

  1. We store our apps working directory in DEPLOYDIR variable
  2. Do a force checkout to the working directory
  3. Change to the working directory
  4. Stop forever
  5. Install any dependencies from our package.json
  6. Start forever
  7. Print out a fun message...

There might be bunch of other stuff you want to do here or modify the commands to say: set the Node environment variable when running forever etc but for our purposes here it's fine.

Next we need to make the post-receive hook executable so:

$ chmod +x post-receive

And that's it our pi side is done!

Local project setup

Now that the pi side is setup let's setup where you'll actually be working. I'm assuming you already have git installed, if not do that now.

Now this next bit is entirely optional but highly recommended:

If you are on Linux with ssh-copy-id already installed amazing! If not install ssh-copy-id-for-OSX it's simply excellent!

$ ssh-copy-id pi@192.168.1.90

This will stop bugging you for password every time you want to SSH into your pi or when you are deploying files.

So let's create a new git repo locally to hold our project:

$ git init testing_app

Next we need to setup a new remote:

$ cd testing_app
$ git remote add pi pi@192.168.1.90:testing_app.git

This sets up a new remote repository called pi and points it at our bare repository on the pi.

Testing the setup

Here I'm assuming you already have Node installed locally, if not visit nodejs.org and follow their excellent guides.

To start lets create package.json file:

$ npm init

After you've obliterated your enter key (or filled it in like an adult) you should have package.json file, we won't need this yet but it stops our post-receive hooks npm install complaining about the file missing.

Next create index.js file in your favourite text editor:

var http = require('http');  
http.createServer(function (req, res) {  
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello? Yes, this is Pi!\n');
}).listen(1337);

We'll add the files, commit and push:

$ git add -A
$ git commit -m "Go pi"
$ git push pi

Now if you point your internet browsing device of choice to 192.168.1.90:1337 you'll be greeted by the Pi! Woo!

Or if you're a baller:

$ curl 192.168.1.90:1337

Go ahead, change some files, commit and push and you should see the forever stopping, npm install running and forever starting up again.

Hooray we are done! I hope you found this helpful and will get you started playing with your pi.

Please promise if you will be using the pi for anything other than playing around do further setup and configuration to ensure security and stability! This is only meant for setting up a quick environment for experimenting with

Let me know what you think on twitter @efexen or via email [fxn at fxndev dot com] and stay tuned for updates on the project