Skip to content

Instantly share code, notes, and snippets.

@agilous
Last active December 11, 2015 04:19
Show Gist options
  • Save agilous/4544643 to your computer and use it in GitHub Desktop.
Save agilous/4544643 to your computer and use it in GitHub Desktop.
Deploying a Ruby on Rails demo app to Heroku from a Raspberry Pi.

Pi+RoR+Heroku Demo

Background

Over the course of the past two school years, my colleague Rob Biedenharn and I have been working with Tom Brinkmann's students at Little Miami High School, attempting to teach them Web development using Ruby on Rails to aid in their participation in Business Professionals of America competitions and to provide them with skills very much in demand locally.

We provided the students all the usual links to facilitate self-guided learning on Windows PCs but it quickly became evident that we were facing two challenges:

  1. Providing the students a development environment similar to what they will encounter in a professional setting.

  2. Maintaining student engagement.

After much trial and error, constrained primarily by the school's existing Windows-based PC labs and no capital to change that fact, we were faced with the fact that there is no substitute for a Unix-based operating system for hosting Rails projects.

Having a development environment that closely resembles the production environment builds the developer's competance and confidence in dealing with production system administration issues since they're likely to have dealt with similar issues on their development system. Arguably, apps deployed to Heroku are hosted in anything but a typical Linux environment but despite Heroku's best efforts (and we LOVE Heroku) most Rails apps running in the wild are hosted on "traditional" Linuxes.

The ability to stand-up a development system for minimal cost was crucial to overcoming the second constraint above. The Raspberry Pi running an Open Source operating system (Debian Linux in our case) met that criteria perfectly.

Prerequisites

  • You'll need (to have access to) a Mac or Linux computer (if you've devised a mean of completing the steps below on a Windows PC then by all means email me!)
  • Basic knowledge about command line navigation in OSX or Linux will aid in comprehension of this guide.
  • If you don't already have one, you'll need to sign up for a Heroku account.

Before We Begin...

If you don't have a Pi, get one! If you have one but don't have the operating system installed, grab this image and follow these instructions using a Mac or Linux computer that has an SD card reader embedded or attached:

  1. Insert a 16GB SD card.

  2. Download this disk image file.

  3. Open a terminal window and change directory to the location into which you downloaded the disk image file above. Then expand the disk image file using this command:

    gunzip rpi.img.gz

  4. Enter this command to locate your SD card:

    diskutil list

  5. Run the command below to unmount but not eject your SD card. Note that the question mark (?) is the disk number which will be specific to your system.

    diskutil unmountDisk /dev/disk?

  6. Copy the disk image to your SD card by running the command below carefully substituting in the disk number obtained in the step above. Note that you will need run this command in the same directory where you downloaded and expanded the disk image file.

    dd if=rpi.img bs=1m of=/dev/rdisk?

There! You're all set to proceed.

SECURITY WARNING!!

The disk image above contains ssh public keys for both Rob and me. This enables us to gain "emergency" access to a student's system. If you do not wish for Rob or me to have access to your system you will need to run the following command on the system:

rm /home/pi/.ssh/authorized_keys

WARNING!!! If you’re going to mess up, here are the likely culprits!

  • Your Pi needs Internet access to complete these tasks. Is the Ethernet cable plugged in?
  • You’ll need to be patient! Don’t just start typing in commands and then hitting enter repeatedly. Wait for each command to finish running before proceeding.
  • As an addendum to the previous tip, read the output returned after running each command and LOOK FOR ALL ERRORS.
  • If there are errors, look for typos in the command you just entered. The last command you ran can be accessed by hitting the up arrow (ꜛ) key.
  • Again, computers excel at reproducing errors. They’re junk in, junk out! Be careful you have entered each command exactly as it appears in the instructions below.
  1. Get Pi & Login

Connect the Raspberry Pi to a monitor, keyboard, mouse, and network and plug in the power.

Username: pi
Password: raspberry

Start the GUI

startx
  1. Start Terminal Session

Double click the LXTerminal icon on the desktop to open the terminal window. Enter the command below and look for the "Projects" directory.

ls

If no “Projects” directory make one and change into it:

mkdir -p Projects
cd Projects
  1. Generate Skeleton Rails App

Enter the following command.

rails new grandchildren

Sit back and watch the magic of Ruby-on-Rails as a new (but empty) project is created in the Projects directory.

cd grandchildren
rails server

Double click the Chromium browser link on the desktop. Visit the address: http://localhost:3000/. (This link will only work if you're reading these instructions on your Pi.)

Once you’ve verified that the empty site displays properly (“Welcome aboard” will appear at the top of the page) you need to stop the server by hitting CTRL-C in the LXTerminal window.

  1. Generate Resources & Database

STOP! Type the following line on the command line BUT DO NOT hit enter until the instructor or assistant has validated there are no errors/typos!

rails generate scaffold Offspring name state children:integer grandchildren:integer

Now run this command.

rake db:create db:migrate

IF the migration fails, read the error message carefully. If you can fix things, just redo the migration part as the database file will already have been created.

rake db:migrate

Restart the server:

rails server

Refresh your browser. (And no change... but wait!)

  1. User Experience!

Now visit: http://localhost:3000/offsprings

Enter a first record!

Enter your paternal grandparents’ last name, first name and the state in which they had their kids. How many children did they have and how many grandchildren do they have?

After creating that offspring record, hit “Back” (the link, not the browser button) to return to the list which now has one record.

Then create the record for your maternal grandparents.

Now that you can see a couple records, let’s get this application ready to deploy to the internet on Heroku.

  1. Preparing to Deploy to Heroku

Install the Heroku Toolbelt on your Pi. This takes a while so we will let it run in a separate window as we edit some other files locally. After opening a new LXTerminal window, run:

wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh

That's “hyphen, Q, capital O, hyphen.”

  1. Opening Emacs to Edit Files

There are just a few changes that need to be made in order to deploy your application to the Heroku service.

  • The database locally is SQLite3, but Heroku only supports PostgreSQL.
  • The default index.html file needs to be removed.
  • The Offspring list should be the default page for the application.

Let’s take these one at a time.

Open Emacs (shortcut on the desktop) and choose “File >> Open” and find the “Gemfile” in the project root which is Projects/grandchildren

Where you see the line:

gem 'sqlite3'

We are going to change this to use SQLite3 in development and test environments (which are local to your Raspberry Pi) and PostgreSQL on production (which will be at Heroku).

group :development, :test do
    gem 'sqlite3'
end

group :production do
    gem 'pg', require: false
end

When you’re done making your changes, save them by choosing “File >> Save” from the menu.

We can’t build the pg gem on the Pi so we have to re-run the bundle install avoiding production.

IF you are in the wrong directory, change to the right one with:

cd ~/Projects/grandchildren

Then run this bundle command:

bundle install --without production

Go back to the command line and remove the index file.

rm public/index.html

Edit Rail's routing file using Emacs choosing "File >> Open" and selecting the “routes.rb” file within the config directory. Find the line:

# root :to => 'welcome#index'

Change it to:

root :to => 'offsprings#index'

Note that there are two (2) changes:

  • the ‘#’ at the beginning (which comments out the rest of the line) is removed
  • ‘welcome’ is replaced with ‘offsprings’
  1. To Heroku!

Replace the bold text below with your personal email address and name.

git init .
git config --global user.email "**you@example.com**"
git config --global user.name "**Your Name**"
heroku login
heroku keys:add

If you receive this message:

Could not find an existing public key.
Would you like to generate one? [Yn]

JUST HIT ENTER!

Then proceed with:

heroku apps:create --addons heroku-postgresql:dev

You will receive a response similar to:

Creating desolate-eyrie-5848... done, stack is cedar
Adding heroku-postgresql:dev to desolate-eyrie-5848... done
http://desolate-eyrie-5848.herokuapp.com/ | git@heroku.com:desolate-eyrie-5848.git
Git remote heroku added

The output displays your application’s new URL, in the case above it is: http://desolate-eyrie-5848.herokuapp.com/. Your application will have some other name similar in format to “word-another-9999.”

Next, commit your code (copy it up to your "production" site):

git add .
git commit -m "this is my first commit EVAR"
git push heroku master
heroku run rake db:migrate
heroku restart

Go to your bright shiny new Web app (the URL returned in the step above)!

  1. Done? Logout and Shutdown!

Once you’ve entered some data in your new app and all the proper authorities have inspected your app for correctness simply enter the following command in the terminal window:

sudo /sbin/shutdown -h now

When the screen is blank AND ONLY when the screen is blank you may disconnect your power supply and remove your SD card.


Some troubleshooting tips:

After making a change to your code:

git commit -am "your commit message"

After every single change you make to the code on your local system you’ll need to redeploy to Heroku:

git push heroku master

The app will be automatically (re)started so no need to run a separate ‘heroku restart’ command like was needed when a migration was run.

The Nuclear Option!

If all else fails issue the command below and start again from Step #3:

cd ..
rm -fr ~/Projects/grandchildren

Or a tactical strike to restart at Step #4:

rails destroy scaffold Offspring

If you run into problems with db:migrate or db:create, you can try this command:

rake db:reset

This will attempt to recreate the database file but should that fail, simply enter these two commands:

rm -f db/development.sqlite3 test.sqlite3
rake db:create db:migrate

Wrap-up

If you're not the slightest bit curious about the magical commands you entered completing this tutorial then you're done. Just remember yes, I would like fries with that. :)

However if you are curious then by all means I encourage you to fire up your Pi, login and explore. Your assignments are:

  • What is the purpose of this command? man ls

  • If there's no manual entry for the rails command and I can use rails --help to get help for the rails command, what command can I use to determine which "version" of rails I'm currently running?

  • What's so special about the root user?

Most of all, have fun and let Rob or me know if we can be of any help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment